考虑以下IL代码:
.method public static void Main()
{
ldstr "Starts Here"
call void [mscorlib] System.Console::WriteLine(string)
.try {
ldstr "Try Me!"
call void [mscorlib] System.Console::WriteLine(string)
leave.s Done
}
catch [mscorlib] System.Exception {
ldstr "Catch Me!"
call void [mscorlib] System.Console::WriteLine(string)
leave.s Done
}
Done:
ldstr "Ends Here"
call void [mscorlib] System.Console::WriteLine(string)
ret
}
CLR如何在JIT编码中定义try
块?本机代码的方式如下:
...
00900076 8b0538214703 mov eax,dword ptr ds:[3472138h] ("Starts Here")
...
00900090 8b053c214703 mov eax,dword ptr ds:[347213Ch] ("Try Me!")
...
009000a2 eb1b jmp 009000bf ;// Done
009000a4 8945d4 mov dword ptr [ebp-2Ch],eax
009000a7 8b0540214703 mov eax,dword ptr ds:[3472140h] ("Catch Me!")
...
009000b8 e888293b73 call clr!JIT_EndCatch (73cb2a45)
009000bd eb00 jmp 009000bf ;// Done
;// Done:
009000bf 8b0544214703 mov eax,dword ptr ds:[3472144h] ("Ends Here")
...
009000d6 c3 ret
我们可以看到clr!JIT_EndCatch
但是try
块的开头和结尾在哪里?
答案 0 :(得分:4)
抖动产生的不仅仅是您可以使用调试器轻松看到的机器代码。您需要阅读this answer,它会讨论抖动生成的表以协助垃圾收集器。
它以非常类似的方式进行异常处理,抖动生成SafeSEH实现使用的函数表,让操作系统发现异常过滤器。这样的表具有try-block的开始和结束地址的条目以及过滤器的函数指针。其工作的确切方式严重缺乏记录,异常处理在过去被恶意软件大量使用,谷歌点击“safeseh”并不是我想在此重复的任何内容。在assembler's option的MSDN文章中有一些关于它的粗略信息。我不知道用调试器检查这些表的简单方法。