.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 отсутствует обратный вызов, чтобы указать, когда это произойдет.

Другие вопросы по тегам