在JIT编译生成的函数上设置断点
2012-05-15 00:17
190 查看
在前面已经介绍过,JIT编译器编译了一个函数并将其放在内存中。如果我们知道JIT编译器保存机器代码的位置,就可以使用调试器的bp命令来设置 断点。我们再次使用在前面介绍过的03breakpoint.exe程序,并且试验能否在AddAndPrint函数上设置一个断点。具体来说,我们希望 在第二次调用这个函数时设置一个断点,以便分析其中潜在的错误。在调试器下启动03breakpoint.exe,并继续执行直到程序提示按任意键。按下 任意键,等待并直到第二次提示按下任意键。此时,按下CTRL-C进入调试器。这是在第二个AddAndPrint函数中设置断点的起始位置。第一个任务 就是判断这个函数是否已经被JIT编译器编译,这可以通过SOS命令name2ee来进行判断。命令name2ee的形式如下所示:
参数module name是需要分析的模块,而type or method name则表示需要获得信息的类型名或者方法名。在这里,module name是03breakpoint.exe,而type name为Advanced.NET.Debugging.Chapter3.Breakpoint.AddAndPrint。
可以看到,在最后一行输出中,这个方法的状态为JITTED(表示已经被JIT编译器编译过了),并且编译之后的地址为003e0178。我们可以通过命令U对这段代码做一个简单的完整性检查(sanity check,在后面将进一步讨论),如清单3-9所示。
清单3-9通过反编译JIT生成的代码对JIT地址进行完整性检查
在反汇编代码的第一部分很清楚地表明了传递给命令U的地址参数是正确的。命令U告诉我们,位
于这个地址上的代码是JIT生成代码。此外,下一行则告诉我们与这段代码相对应的方法名(这里是
Advanced.NET.Debugging.Chapter3.Breakpoint.AddAndPrint)。最后,第三行是起始地址
(003e0178)和生成代码的大小(80)。在这些初始信息之后是反汇编后的指令。现在,我们可以找到动态生成代码的正确地址,并且在这个地址上设置
一个断点。如果恢复程序执行(不要忘记按下任意键来启动第二次调用),可以很快地触发断点,如下所示:
在触发断点后,可以使用ClrStack命令来确保触发的是正确的代码位置。
之前,我们希望在第二次调用AddAndPrint时设置一个断点,因为这次的调用中存在一个错误。而现在,我相信你已经知道了为什么要在第二次调
用时设置一个断点,就是因为在一个由JIT编译的函数上设置断点是很容易的(在前一次调用该函数时会使这个函数被JIT编译)。我们可以通过
name2ee命令来找出JIT编译后代码的地址,然后在这个地址上使用bp命令。
这是在设置断点时可以使用的另一种方法。SOS调试器扩展包含了一个命令bpmd,这个命令能够极大地简化工作,它能自动找出被JIT编译后代码的正确地址,并且可以仅根据完整的方法名来设置断点。
接下来,我们来看看如何在还没有被JIT编译的函数上设置断点。毕竟,我们不能总在被JIT编译后的函数上设置断点,有时候还需要在第一次调用函数时就设置断点,而此时函数通常还没有被编译。
清单3-9通过反编译JIT生成的代码对JIT地址进行完整性检查
于这个地址上的代码是JIT生成代码。此外,下一行则告诉我们与这段代码相对应的方法名(这里是
Advanced.NET.Debugging.Chapter3.Breakpoint.AddAndPrint)。最后,第三行是起始地址
(003e0178)和生成代码的大小(80)。在这些初始信息之后是反汇编后的指令。现在,我们可以找到动态生成代码的正确地址,并且在这个地址上设置
一个断点。如果恢复程序执行(不要忘记按下任意键来启动第二次调用),可以很快地触发断点,如下所示:
之前,我们希望在第二次调用AddAndPrint时设置一个断点,因为这次的调用中存在一个错误。而现在,我相信你已经知道了为什么要在第二次调
用时设置一个断点,就是因为在一个由JIT编译的函数上设置断点是很容易的(在前一次调用该函数时会使这个函数被JIT编译)。我们可以通过
name2ee命令来找出JIT编译后代码的地址,然后在这个地址上使用bp命令。
这是在设置断点时可以使用的另一种方法。SOS调试器扩展包含了一个命令bpmd,这个命令能够极大地简化工作,它能自动找出被JIT编译后代码的正确地址,并且可以仅根据完整的方法名来设置断点。
接下来,我们来看看如何在还没有被JIT编译的函数上设置断点。毕竟,我们不能总在被JIT编译后的函数上设置断点,有时候还需要在第一次调用函数时就设置断点,而此时函数通常还没有被编译。
相关文章推荐
- JavaScript DOM用document.createElement()生成元素,用seAttribute()函数设置属性值
- Windbg在Managed App中设置函数断点的几种方法
- Win7下VS2008不能为函数设置断点
- Android Studio 设置之自动生成类注释(增加函数注释模板)
- JavaScript DOM用document.createElement()生成元素,用seAttribute()函数设置属性值
- 破解常用断点设置API函数原型——常用函数汇总
- 【Andrioid】在Gradle编译时生成一个不同的版本号,动态设置应用程序标题,应用程序图标,更换常数
- qmake.exe是在Qt安装编译时生成的,里面内嵌了Qt相关的一些路径(最简单的方法是保持一样的安装路径,最方便的办法是设置qt.conf文件)
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- VisualStudio工程设置(二)---opencv3.2在vs2015开发环境搭建+cmake3.8编译生成opencv x86版本库
- Android编译是否生成odex的设置
- 设置 ASP.NET 存储当前应用程序的临时文件(生成的源、编译了的程序集等)的目录的物理路径。
- JavaScript DOM用document.createElement()生成元素,用seAttribute()函数设置属性值
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- 函数单独编译与函数在main函数中调用编译后生成汇编代码对比
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- Windbg在Managed App中设置函数断点的几种方法
- vs2008中编译动态库时生成lib的设置
- VS反编译文件调试断点无法设置
- JavaScript DOM用document.createElement()生成元素,用seAttribute()函数设置属性值