.NET Profiler вход / выход функции перехватывает не вызывается в случае исключения

Я создаю .Net Profiler для некоторых пользовательских требований.

Я хочу подключиться к Enter и Leave для некоторых конкретных методов. Чтобы добиться этого, я попробовал ниже два подхода.

  1. IL Rewrite — я могу ввести пользовательский код в обоих местах. Он успешно вводится и вызывает пользовательский код. Я также могу получить входные аргументы ‘this’ и возвращаемое значение. Вводить при входе не так уж сложно. Тем не менее, сложно ввести в Leave, так как в методе может быть возврат в нескольких местах. Я должен вводить код в каждом месте, где написано заявление возврата.

    Это немного сложно, но несколько выполнимо. Но, если есть какое-либо исключение, выполнение не достигает оператора return и, следовательно, мой введенный код не вызывается.

  2. Подписаться на Вход / Выход через 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";
}

1

Решение

Чтобы получить уведомление об исключительной ситуации при перезаписи IL, вам нужно ввести try-finally или try-catch-throw. Так как ret инструкция недопустима в блоке try, вам нужно заменить его на leave инструкция, которая переходит к инструкции после вставленного обработчика исключений и возвращается оттуда.

Другой вариант — включить COR_PRF_MONITOR_EXCEPTIONS в вашем звонке SetEventMask и слушать на ExceptionUnwindFunctionEnter а также ExceptionUnwindFunctionLeave Обратные вызовы. Эти обратные вызовы не включают брошенное исключение как бы то ни было. Вы могли бы трек исключение из ExceptionThrown, но это может вводить в заблуждение, когда исключение покидает блок фильтра, так как среда выполнения будет обрабатывать его как возвращающий false и продолжать с предыдущим исключением, но в IIRC отсутствует обратный вызов, чтобы указать, когда это произойдет.

1

Другие решения

Других решений пока нет …