当前位置:  开发笔记 > 编程语言 > 正文

调试.NET CLR应用程序时,如何查看评估堆栈上的局部变量?

如何解决《调试.NETCLR应用程序时,如何查看评估堆栈上的局部变量?》经验,为你挑选了1个好方法。

我正在使用Windbg(具有sos扩展),并尝试调试崩溃的应用程序。我能够转储引发异常的调用的IL,并且通过检查代码,如果可以转储评估堆栈的内容,似乎可以获得所需的信息。WinDbg&sos可以做什么?

这是我所做的:

    开始WinDbg

    附加到崩溃的进程

    loadby sos mscorwks (加载sos扩展名)

    !token2ee theModuleName 0600009a (其中,ModuleName是我正在调试的应用程序(和程序集)的名称,9a是Windows错误报告工具报告的崩溃方法的方法偏移量。我得到以下输出:

    模块:000e2c3c(theApplicationName.exe)
    令牌:0x0600009a方法描述
    :000e67c8
    名称:MyNamespace.MyClassName.theCulpritFn(MyOtherClass)
    JITTED代码地址:0081b1d0

    !dumpil 00e67c8 (为相关方法转储了IL)。这是输出:

    // ..
    // .. the previous code omitted for brevity
    .catch
    {
     IL_0071: stloc.0
     IL_0072: nop
     IL_0073: ldstr "Can't set CurrentServer property for: "
     IL_0078: ldarg.0
     IL_0079: ldfld MyNamespace.MyClassName::_currentServer
     IL_007e: brtrue.s IL_0087
     IL_0080: ldstr ""
     IL_0085: br.s IL_0092
     IL_0087: ldarg.0
     IL_0088: ldfld MyNamespace.MyClassName::_currentServer
     IL_008d: callvirt MyNamespace.MyOtherClass::get_Name
     IL_0092: call System.String::Concat
     IL_0097: ldloc.0
     IL_0098: newobj MyNamespace.MySpecialExceptionType::ctor
     IL_009d: throw
    } 
    

    问题是:在抛出异常之前,我是否有办法查看堆栈中已推送的内容。如果我没记错的话,传入异常构造函数的参数应该是评估堆栈上索引0处的局部变量。

    PS:当我尝试调用!clrstack -a时,出现一条消息:无法遍历托管堆栈。当前线程可能不是托管线程。您可以运行!threads来获取进程中托管线程的列表。

谢谢!



1> Brian Rasmus..:

您需要确定并选择正确的线程。当前线程的ID显示在WinDbg提示符中。

!threads将显示应用程序中的所有托管线程。一旦确定,您就可以使用~XsX是该线程的WinDbg ID 来切换线程。

!clrstack将显示堆栈跟踪。如果要使用本地语言和/或参数,请使用-l/ -p(或-a同时使用两者)。

您可以遍历所有线程,并使用列出它们的调用堆栈~*e!clrstack

如果局部/参数不能满足您的需求,请使用!dso来显示推入堆栈的对象。

推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有