如何查明程序中使用.dmp和WinDbg发生崩溃的地方?



我有一个巨大的应用程序(在PowerBuilder中制作),每隔一段时间崩溃一次,所以很难重现这个错误。我们设置了它,这样当发生这样的崩溃时,我们会收到一个.dmp文件。

我使用WinDbg分析我的.dmp使用命令"!analyze -v. conf"创建文件。由此我可以推断出发生的错误是访问违规C0000005。根据[0]和[1]参数,它试图解引用一个空指针。

WinDbg还向我展示了由大约30行组成的STACK_TEXT,但我不确定如何阅读它。根据我所看到的,我需要使用一些符号。

我的STACK_TEXT第一行是这样的:

00000000`00efca10 00000000`75d7fa46     : 00000000`10df1ae0 00000000`0dd62828 00000000`04970000 00000000`10e00388 : pbvm!ob_get_runtime_class+0xad

从这里,我的目标是分析这个文件,找出这个错误发生在程序中的确切位置或它在哪个函数中。这是我将能够在进一步分析堆栈跟踪后找到的东西吗?

我怎么能查明在哪里程序崩溃发生使用。dmp和WinDbg,所以我可以修复我的代码?

如果使用!analyze -v分析崩溃转储,则STACK TEXT之后的行是堆栈跟踪。如果设置了正确的线程和上下文,输出相当于kb

kb的输出为

儿童EBP
  1. 返回地址
  2. 堆栈上的前4个值

反引号`告诉你你在64位运行,他们在中间分割64位值。

在32位上,堆栈上的前4个参数通常相当于函数的前4个参数,具体取决于调用约定。

在64位上,堆栈不再那么相关,因为在64位调用约定中,参数通过寄存器传递。因此,您可以忽略这些值。

有趣的部分是符号像pbvm!ob_get_runtime_class+0xad!前面是模块名称,通常是DLL或EXE名称。寻找你创造的东西。!之后和+之前是一个方法名。+后面是距离函数开始的偏移量,以字节为单位。

只要你没有数千行代码的函数,这个数字应该很小,像<0 x200型。如果这个数字比这个大,通常意味着你没有正确的符号。在这种情况下,方法名不再可靠,因为它可能只是最后一个已知的(最后导出的)方法名,并且从那里走了很远的路,所以不要相信它。

pbvm!ob_get_runtime_class+0xad的情况下,pbvm是DLL名,ob_get_runtime_class是方法名,+0xad是指令指针所在方法内的偏移量。

对我(对PowerBuilder一无所知)来说,PBVM听起来像PowerBuilder虚拟内存的DLL实现。这不是你的代码,这是Sybase编译的代码。你需要在调用堆栈中进一步查找DLL中的错误代码。

在阅读维基百科之后,似乎PowerBuilder并不一定编译成本机代码,而是编译成中间的p代码。在这种情况下,您可能不太幸运,因为您的代码从未真正在调用堆栈上,并且您需要一个特殊的调试器或WinDbg扩展(可能不存在,如Java)。使用-pbdebug命令行开关运行它,或者将其编译为本机代码,然后让它再次崩溃。

相关内容

  • 没有找到相关文章

最新更新