我正在为某些自定义需求构建.Net Profiler。.NET Profiler进入/离开函数挂钩不会在异常情况下调用
我想挂钩在输入和离开一些特定的方法。为了达到这个目的,我尝试了两种方法。
IL重写 - 我能够在两个地方注入自定义代码。它已成功注入并调用自定义代码。我也能够得到输入参数'this'并返回值。在Enter处注入并不困难。然而,在Leave中注入很复杂,因为在方法中可能会有多个地方返回。我必须在写入return语句的每个地方注入代码。
这有点复杂,但有点可行。但是,如果有任何异常,执行没有达到返回语句,因此我的注入代码没有被调用。
根据给出的样本代码here订阅Enter /通过
SetEnterLeaveFunctionHooks2
在ICorProfilerInfo2
中。
在这两种情况下,在方法中发生异常的情况下,不会调用Leave。
如何处理?我想要在所有情况下的返回值。如果有例外,我应该知道有一个例外;我会考虑为'没有回报价值'。也许,我可能也需要异常细节。
下面是一个示例方法。我想在Enter和Leave for 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";
}
很难理解这一点。如果你打算使用profiler api来重写IL,那么你最好在代码开始执行之前这么做。换句话说,您需要JITCompilationStarted回调。如果你使用SetEnterLeaveFunctionHooks2来实现,那么死亡就会被施放,IL已经得到了解决,并且改变它不会有任何影响。有了另外一个明显的优点,那就是当你用JITCompilationStarted完成时,你不必再担心异常。 –
@HansPassant,对于IL Rewrite,我在ModuleLoadFinished回调中执行,一切正常,我的代码被注入并在正常执行流程中调用。但是,如果我在GetValue方法中取消注释抛出异常语句,它不会被调用(由于显而易见的原因)。 GetValue仅仅是示例代码插图的目的,在实际场景中异常随时可以得到。 – Hitesh