1

我正在为一些自定义要求构建一个 .Net Profiler。

我想在 Enter 和 Leave 中加入一些特定的方法。为此,我尝试了以下两种方法。

  1. IL Rewrite - 我能够在这两个地方注入自定义代码。它已成功注入并调用自定义代码。我还能够获取输入参数“this”和返回值。在 Enter 注入并不难。但是,在离开时注入很复杂,因为方法中可能在多个位置返回。我必须在每个编写 return 语句的地方注入代码。

    这有点复杂,但有点可行。但是,如果有任何异常,执行不会到达 return 语句,因此我注入的代码不会被调用。

  2. 根据此处SetEnterLeaveFunctionHooks2给出的ICorProfilerInfo2示例代码订阅进入/退出。

在这两种情况下,如果方法中出现异常,则不会调用 Leave 处的钩子。

如何处理?我想要所有场景中的返回值。如果出现异常,我应该知道有异常;我会认为是“没有返回值”。可能,我可能还需要异常详细信息。

下面是一个示例方法。我想为 GetString 方法挂钩 Enter 和 Leave。它有多个回报。我能够在正常情况下捕获返回值。但是在出现异常的情况下,执行会立即停止,因为返回时的钩子没有被调用。

    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";
    }
4

1 回答 1

2

要在使用 IL 重写时获得异常通知,您需要注入 try-finally 或 try-catch-throw。由于该ret指令在 try 块中无效,因此您需要将它们替换为leave在插入的异常处理程序之后分支到指令并从那里返回的指令。

另一种选择是COR_PRF_MONITOR_EXCEPTIONS在您的呼叫中包括SetEventMask并收听ExceptionUnwindFunctionEnterExceptionUnwindFunctionLeave回调。然而,这些回调不包括抛出的异常。您可以从跟踪异常ExceptionThrown,但是当异常离开过滤器块时这可能会产生误导,因为运行时会将其视为返回 false 并继续前一个异常,但是 IIRC,没有回调来指示何时发生这种情况。

于 2017-09-23T01:23:50.150 回答