我调查了.Net Framework JITter的编译结果,并希望以编程方式获取异常处理程序链。可能有人可以帮助我进行这项调查吗?

为了简化任务,我调试了以下代码:

class Program
{
    static void Main(string[] args) { MethodA(); }

    static void MethodA() { MethodB(); }

    static void MethodB() 
    {
        try { MethodC(); } 
          catch (Exception exception)  { MethodC(); }
    }

    static void MethodC() { MethodD(); }

    static void MethodD()
    {
        try { MethodE(); }
          catch (Exception exception) { MethodE(); }
    }

    static void MethodE() { throw new Exception(); }
}


找到了什么?


JITter使用标准方法构建堆栈帧(局部变量,EBPEIP,params)
第一个参数通过寄存器(快速调用)移到方法中。我不知道。真。方法没有任何代码可以注销链中的最后一个处理程序。
静态方法仅压入EBPEIP。这意味着,堆栈不能包含链,并且链不在堆栈中。

我使用的工具:MS Visual Studio 2010,SOS扩展,用于按地址解析.Net对象和元数据。 VMMap可以了解,通过给定的地址和(呵呵)MS OneNote可以标记哪种类型的内存页,以不同的颜色标记内存转储以标记为已解析(这意味着,我了解我所发现的内容)

我将很高兴了解这条链在哪里,但我没有经验。

重要说明:CLR不会将SEH用于例外情况(很多文章,作者在CLR中都写过SEH的谎言。 CLR仅包装SEH以将其异常转换为CLR类型)

评论

我认为stackoverflow.com/q/19111108/731115可以为您提供帮助。

谢谢,但是我在寻找复杂的答案。就像在SEH(结构化异常处理)中一样:要获取链头,我们需要读取FS:0,在这里我们可以找到.......

由于这是一个非常狭窄的域,因此建议您搜索与clr相关的资源-在此获得答案的机会很小。.

#1 楼

我无法直接告诉您它是如何工作的,但是也许这将有助于找到答案。

首先,您想在CLR级别上进行调试-这就是与您的CLR指令有关的所有内容代码以及它们如何安装新的异常处理程序。一旦可以在调试器中完成操作,就可以使用CLR调试API进行自动化。

http://msdn.microsoft.com/zh-CN/library/vstudio/bb397953(v=vs.100 ).aspx

“ CLR调试服务提供了几种控制程序执行的方法。这些方法包括断点,单步执行,异常通知,函数求值以及其他与启动和关闭有关的事件程序。”

基本上,如果您可以理解安装新处理程序并在引发异常时查找处理程序的机制,则可以从那里扩展。也许这个api可能没有帮助。