.NET Profiler enter/leave 函数挂钩在异常情况下不会被调用
.NET Profiler enter/leave function hooks does not get called in case of exception
我正在为某些自定义要求构建 .Net Profiler。
我想在 Enter 和 Leave 上挂钩一些特定的方法。为此,我尝试了以下两种方法。
IL Rewrite - 我可以在这两个地方注入自定义代码。它已成功注入并调用自定义代码。我还可以获得输入参数 'this' 和 return 值。在 Enter 处注入并不难。但是,在 Leave 处注入很复杂,因为方法中的多个位置可能有 return。我必须在每个写 return 语句的地方注入代码。
它有点复杂但有点可行。但是,如果有任何异常,执行不会到达 return 语句,因此我注入的代码不会被调用。
根据给定的示例代码 here.
在 ICorProfilerInfo2
中通过 SetEnterLeaveFunctionHooks2
订阅 Enter/Leave
在这两种情况下,如果方法中出现异常,则不会调用 Leave 处的挂钩。
如何处理?我想要在所有场景中都有一个 return 值。万一有例外,我应该知道有例外;我会考虑为'No return value'。可能,我可能还需要异常详细信息。
下面是一个示例方法。我想挂钩 Enter 和 Leave 以获得 GetString 方法。它有多个 return。我能够在正常情况下捕获 return 值。但如果出现异常,执行会立即停止,因此 return 处的挂钩不会被调用。
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
指令,该指令分支到插入的异常处理程序之后的指令和 return 从那里。
另一种选择是在对 SetEventMask
and listen on the ExceptionUnwindFunctionEnter
and ExceptionUnwindFunctionLeave
callbacks. These callbacks don't include the thrown exception however. You could track the exception from ExceptionThrown
的调用中包含 COR_PRF_MONITOR_EXCEPTIONS
,但当异常离开过滤器块时,这可能会产生误导,因为运行时会将其视为 returning false 并继续之前的异常,但是 IIRC,没有回调来指示何时发生这种情况。
我正在为某些自定义要求构建 .Net Profiler。
我想在 Enter 和 Leave 上挂钩一些特定的方法。为此,我尝试了以下两种方法。
IL Rewrite - 我可以在这两个地方注入自定义代码。它已成功注入并调用自定义代码。我还可以获得输入参数 'this' 和 return 值。在 Enter 处注入并不难。但是,在 Leave 处注入很复杂,因为方法中的多个位置可能有 return。我必须在每个写 return 语句的地方注入代码。
它有点复杂但有点可行。但是,如果有任何异常,执行不会到达 return 语句,因此我注入的代码不会被调用。
根据给定的示例代码 here.
在ICorProfilerInfo2
中通过SetEnterLeaveFunctionHooks2
订阅 Enter/Leave
在这两种情况下,如果方法中出现异常,则不会调用 Leave 处的挂钩。
如何处理?我想要在所有场景中都有一个 return 值。万一有例外,我应该知道有例外;我会考虑为'No return value'。可能,我可能还需要异常详细信息。
下面是一个示例方法。我想挂钩 Enter 和 Leave 以获得 GetString 方法。它有多个 return。我能够在正常情况下捕获 return 值。但如果出现异常,执行会立即停止,因此 return 处的挂钩不会被调用。
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
指令,该指令分支到插入的异常处理程序之后的指令和 return 从那里。
另一种选择是在对 SetEventMask
and listen on the ExceptionUnwindFunctionEnter
and ExceptionUnwindFunctionLeave
callbacks. These callbacks don't include the thrown exception however. You could track the exception from ExceptionThrown
的调用中包含 COR_PRF_MONITOR_EXCEPTIONS
,但当异常离开过滤器块时,这可能会产生误导,因为运行时会将其视为 returning false 并继续之前的异常,但是 IIRC,没有回调来指示何时发生这种情况。