Я создаю .Net Profiler для некоторых пользовательских требований.
Я хочу подключиться к Enter и Leave для некоторых конкретных методов. Чтобы добиться этого, я попробовал ниже два подхода.
IL Rewrite — я могу ввести пользовательский код в обоих местах. Он успешно вводится и вызывает пользовательский код. Я также могу получить входные аргументы ‘this’ и возвращаемое значение. Вводить при входе не так уж сложно. Тем не менее, сложно ввести в Leave, так как в методе может быть возврат в нескольких местах. Я должен вводить код в каждом месте, где написано заявление возврата.
Это немного сложно, но несколько выполнимо. Но, если есть какое-либо исключение, выполнение не достигает оператора return и, следовательно, мой введенный код не вызывается.
Подписаться на Вход / Выход через SetEnterLeaveFunctionHooks2
в ICorProfilerInfo2
согласно приведенному образцу кода Вот.
В обоих случаях hook at the Leave не вызывается в случае исключения в методе.
Как справиться с этим? Я хочу вернуть значение во всех сценариях. В случае исключения я должен знать, что есть исключение; Я буду считать «Нет возвращаемого значения». Возможно, мне также могут понадобиться подробности исключений.
Ниже приведен пример метода. Я хочу подключиться к Enter и Leave для метода GetString. Он имеет несколько возвратов. Я могу захватить возвращаемое значение в обычном сценарии. Но в случае исключения, выполнение немедленно останавливается и из-за этого ловушка при возврате не вызывается.
public int GetInt()
{
//int retVal = 10;
int retVal = 1010;
//throw new Exception("test");
return retVal;
}
public string GetString()
{
var retunValue = "Return string ";
if (GetInt() > 100)
{
retunValue += " inside IF > 100";
return retunValue;
}
return retunValue + " at last return";
}
Чтобы получить уведомление об исключительной ситуации при перезаписи IL, вам нужно ввести try-finally или try-catch-throw. Так как ret
инструкция недопустима в блоке try, вам нужно заменить его на leave
инструкция, которая переходит к инструкции после вставленного обработчика исключений и возвращается оттуда.
Другой вариант — включить COR_PRF_MONITOR_EXCEPTIONS
в вашем звонке SetEventMask
и слушать на ExceptionUnwindFunctionEnter
а также ExceptionUnwindFunctionLeave
Обратные вызовы. Эти обратные вызовы не включают брошенное исключение как бы то ни было. Вы могли бы трек исключение из ExceptionThrown
, но это может вводить в заблуждение, когда исключение покидает блок фильтра, так как среда выполнения будет обрабатывать его как возвращающий false и продолжать с предыдущим исключением, но в IIRC отсутствует обратный вызов, чтобы указать, когда это произойдет.
Других решений пока нет …