【问题标题】:Interpreting Stacks in Windows Minidumps解释 Windows Minidump 中的堆栈
【发布时间】:2010-09-09 19:47:12
【问题描述】:

作为一个刚刚开始学习复杂的计算机调试的人,我一生都无法理解如何阅读 Windbg 中转储的堆栈文本。我不知道从哪里开始如何解释它们或如何去做。谁能给这个可怜的灵魂指路?

ie(实际上是我手头上唯一的垃圾场)

>b69dd8f0 bfa1e255 016d2fc0 89efc000 00000040 nv4_disp+0x48b94

b69dd8f4 016d2fc0 89efc000 00000040 00000006 nv4_disp+0x49255

b69dd8f8 89efc000 00000040 00000006 bfa1dcc0 0x16d2fc0

b69dd8fc 00000000 00000006 bfa1dcc0 e1e71018 0x89efc000

我知道问题与 Nvidia 显示驱动程序有关,但我想知道如何实际读取堆栈(例如,b69dd8f4 是什么?):-[

【问题讨论】:

    标签: multithreading windbg stack-trace


    【解决方案1】:

    首先,您需要配置正确的符号。这些符号将允许您将内存地址与函数名称相匹配。为此,您必须在您的机器中创建一个本地文件夹,您将在其中存储符号的本地缓存(例如:C:\symbols)。然后您需要指定符号服务器路径。为此,只需转到:文件 > 符号文件路径并输入:

    SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
    

    您可以找到有关如何正确配置符号here 的更多信息。

    正确配置 Symbols 服务器后,您可以从以下位置打开小型转储:文件 > 打开故障转储。

    打开小型转储后,它会在命令行左侧显示生成转储时正在执行的线程。如果你想看看这个线程正在执行什么类型:

    kpn 200
    

    第一次执行它可能需要一些时间,因为它必须在第一次下载必要的公共 Microsoft 相关符号。下载完所有符号后,您将获得如下内容:

    01 MODULE!CLASS.FUNCTIONNAME1(...)
    02 MODULE!CLASS.FUNCTIONNAME2(...)
    03 MODULE!CLASS.FUNCTIONNAME3(...)
    04 MODULE!CLASS.FUNCTIONNAME4(...)
    

    地点:

    • 第一个数字:表示帧号
    • MODULE:包含代码的DLL
    • CLASS:(仅适用于 C++ 代码)将显示包含该代码的类
    • FUNCTIONAME:被调用的方法。如果您有正确的符号,您还将看到参数。

    你可能还会看到类似的东西

    01 MODULE!+989823
    

    这表明您没有此 DLL 的正确符号,因此您只能看到方法偏移量。

    那么,什么是调用栈?

    想象一下你有这个代码:

    void main()
    {
      method1();
    }
    
    void method1()
    {
      method2();
    }
    
    int method2()
    {
      return 20/0;
    }
    

    在这段代码中,method2 基本上会抛出一个异常,因为我们试图除以 0,这将导致进程崩溃。如果我们在发生这种情况时得到一个小型转储,我们将看到以下调用堆栈:

    01 MYDLL!method2()
    02 MYDLL!method1()
    03 MYDLL!main()
    

    您可以从此调用堆栈中跟踪“main”调用“method1”,然后调用“method2”并失败。

    在你的情况下,你有这个调用堆栈(我猜这是运行“kb”命令的结果)

    b69dd8f0 bfa1e255 016d2fc0 89efc000 00000040 nv4_disp+0x48b94
    b69dd8f4 016d2fc0 89efc000 00000040 00000006 nv4_disp+0x49255
    b69dd8f8 89efc000 00000040 00000006 bfa1dcc0 0x16d2fc0
    b69dd8fc 00000000 00000006 bfa1dcc0 e1e71018 0x89efc000
    

    第一列表示子帧指针,第二列表示正在执行的方法的返回地址,接下来的三列显示传递给方法的前3个参数,最后一部分是DLL名称(nv4_disp) 和正在执行的方法的偏移量 (+0x48b94)。由于您没有符号,因此您无法看到方法名称。我怀疑 NVIDIA 是否提供对其符号的公共访问权限,所以我猜你无法从这里获得太多信息。

    我建议您运行“kpn 200”。这将向您显示完整的调用堆栈,您可能会看到导致此崩溃的方法的来源(如果它是 Microsoft DLL,您应该在我提供的步骤中包含正确的符号)。

    至少您知道它与 NVIDIA 错误有关 ;-) 尝试将此驱动程序的 DLL 升级到最新版本。

    如果您想了解更多有关 WinDBG 调试的信息,我推荐以下链接:

    【讨论】:

    • 这个答案太棒了。所以应该有更多这样的答案。
    【解决方案2】:

    这里有一个非常好的解释堆栈跟踪的教程:

    http://www.codeproject.com/KB/debug/cdbntsd2.aspx

    但是,即使有这样的教程,如果没有可用/加载的正确符号,也很难(或几乎不可能)解释堆栈转储。

    【讨论】:

      【解决方案3】:

      包含您尝试阅读的堆栈的示例可能会有所帮助。一个好的提示是确保堆栈中显示的所有模块都有正确的调试符号。这包括操作系统中模块的符号,微软已经公开了他们的符号服务器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-03
        • 1970-01-01
        • 2015-10-21
        • 2012-05-15
        • 2011-05-04
        • 2013-09-10
        • 2011-07-20
        相关资源
        最近更新 更多