针对优化托管调试的反汇编改进

马克·唐尼

如果你专注于为自己挤出最后一点表现。NET服务或应用程序,您可以选择利用JIT编译器优化。然而,调试优化的代码可能是一个挑战。在这个博客中,我将向您展示反汇编窗口以及16.7中的最新改进如何帮助您调试优化的代码。

优化代码时会发生什么?

当JIT编译器优化代码时,它可能会重新组织指令,目的是生成更快、更高效的编译代码。在这些更改之后,调试器工具,如Visual Studio或WinDbg公司,可能并不总是能够立即识别与一组指令对应的源代码。

编译器优化还可能通过删除局部变量或将其移动到调试器无法分析的位置来影响局部变量。当优化合并代码块时,代码行变得不一致。如果优化器合并两个函数,调用堆栈上的帧的函数名也可能更改。

调试优化代码时,您可能会看到以下组合:

  • 断点可能并不总是绑定到匹配的寻源位置。
  • 步进可能并不总是步进到正确的位置。
  • 某些变量可能无法进行评估。

考虑到这些更改,即使您可以直接访问源代码,或者即使您可以利用反编译。不用担心,Visual Studio有一个反汇编窗口这使您能够检查每个优化指令的每个细节!

查看反汇编代码

“反汇编”窗口显示与编译器创建的指令直接对应的程序集代码。如果您正在调试托管代码,那么汇编指令与实时(JIT)编译器创建的本机代码相关。

要在实时或转储调试期间打开“反汇编”窗口,请选择窗口>反汇编(ctrl+k)。使用“反汇编”窗口。使用Visual Studio调试托管代码时,“反汇编”窗口显示与JIT编译器创建的指令相对应的汇编代码。

找到它的来源空引用异常

未处理的Null引用异常是我们看到的生产应用程序崩溃的最常见原因之一。由于各种原因,包括数据丢失或配置设置不正确,它们可能会在生产中意外发生。当你成功捕获崩溃转储,只需在VisualStudio中打开转储可以导航到出错的线程、调用堆栈甚至代码行。

例如,如果您有一个Null Reference Exception,并且您想尝试找出优化转储中出现错误的对象(局部变量通常不可用),这可能非常困难,但是,“反汇编”窗口可以更清楚地指示出有问题的对象。

在本例中,我使用改进的托管反汇编窗口,其中包含从托管进程收集的崩溃转储。在这个视图中,我覆盖了编译器创建的汇编代码和源代码,这有助于我确定“[rbp-8]'是where对象'hnd1型'定义,并且属性“文件处理程序“确实是由于试图解除对null的保护而观察到的崩溃的根源。

显示Visual Studio反汇编

在Visual Studio中诊断获胜!

如果您正在调试优化的进程或转储,可能需要熟悉反汇编窗口。即使对于优化的托管进程,您也可以有效地挖掘所有可用指令的每个细节,并将这些指令与可行的源代码位置相匹配。

下载最新版本的Visual Studio并试用!

我们一直在寻找改进诊断和调试体验的方法,无论是在实时还是转储场景中。请前往开发人员社区报告问题或建议Visual Studio的新功能。你也可以在推特上直接联系我(@罂粟花).

2条评论

讨论结束。登录以编辑/删除现有评论。

  • 托马斯·布拉斯克·约根森 0

    在那张图片中,您没有覆盖IL指令和源代码。
    您覆盖了x86指令和源代码。

    • 马克·唐尼Microsoft员工 0

      啊,是的,我错了。已更正。谢谢托马斯!

      马克·唐尼

反馈usabilla图标