解释Windows Minidumps中的堆栈
作为一个刚开始学习计算机调试的复杂知识的人,我一生都无法理解如何在Windbg中读取转储的堆栈文本。我不知道从哪里开始如何解释它们或者如何着手。谁能为这个可怜的灵魂提供指导?
即(实际上是我手头唯一的垃圾箱)
>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是什么?):-[
解决方案
回答
包含我们尝试读取的堆栈的示例可能会有所帮助。一个很好的技巧是确保我们对堆栈中显示的所有模块具有正确的调试符号。这包括操作系统中模块的符号,Microsoft已将其符号服务器公开可用。
回答
http://support.microsoft.com/kb/315263
和
http://www.networkworld.com/news/2005/041105-windows-crash.html
回答
此处提供了有关解释堆栈跟踪的非常好的教程:
http://www.codeproject.com/KB/debug/cdbntsd2.aspx
但是,即使有了这样的教程,在没有适当的可用符号/未加载符号的情况下,也很难(或者几乎不可能)解释堆栈转储。
回答
首先,我们需要配置正确的符号。这些符号将使我们可以将内存地址与功能名称进行匹配。为此,我们必须在计算机中创建一个本地文件夹,我们将在其中存储符号的本地缓存(例如:C:\ symbols)。然后,我们需要指定符号服务器路径。为此,请转到:文件>符号文件路径,然后键入:
SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
我们可以在此处找到有关如何正确配置符号的更多信息。
正确配置Symbols服务器后,我们可以从以下位置打开小型转储:"文件">"打开故障转储"。
打开小型转储后,它将在命令行的左侧显示生成转储时正在执行的线程。如果要查看该线程正在执行的内容,请输入:
kpn 200
第一次执行可能会花费一些时间,因为它必须首次下载必要的与Microsoft相关的公共符号。下载所有符号后,我们将获得类似以下内容的信息:
01 MODULE!CLASS.FUNCTIONNAME1(...) 02 MODULE!CLASS.FUNCTIONNAME2(...) 03 MODULE!CLASS.FUNCTIONNAME3(...) 04 MODULE!CLASS.FUNCTIONNAME4(...)
在哪里:
- 第一个:表示帧号
- 模块:包含代码的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
第一列指示子框架指针,第二列指示正在执行的方法的返回地址,后三列显示传递给该方法的前三个参数,最后一部分是DLL名称(nv4_disp)以及正在执行的方法的偏移量(+ 0x48b94)。由于没有符号,因此无法看到方法名称。我怀疑NVIDIA是否可以公开访问其符号,因此我想我们无法从此处获得太多信息。
我建议我们运行" kpn 200"。这将向我们显示完整的调用堆栈,并且我们也许能够看到导致此崩溃的方法的来源(如果它是Microsoft DLL,则在我提供的步骤中应具有正确的符号)。
至少我们知道它与NVIDIA错误有关;-)尝试将该驱动程序的DLL升级到最新版本。
如果我们想了解有关WinDBG调试的更多信息,建议我们使用以下链接:
- 如果损坏了,应该修复它
- TechNet网络广播:Windows挂起和崩溃转储分析
- Delicious.com在WinDBG上的流行链接