过去几天一直在调试一个非常奇怪的问题。为在Windows上运行的i386构建的应用程序崩溃,调用堆栈的顶部完全损坏,指令指针处于无意义的位置。
经过一番努力,我重建了callstack并且能够确定IP如何在无意义的位置结束。 boost共享指针代码中的指令尝试使用不正确的偏移调用我的DLL导入地址表中定义的函数。该指令看起来像:
call dword ptr [nonsense offset into import address table]
结果,执行最终导致了一个糟糕的位置,不幸的是,这个位置是可执行的。执行然后继续进行,吞噬堆栈顶部直到最终崩溃。
通过在我的电脑上启动相同的应用程序,并进入有问题的代码,我可以找到相同的调用指令,并通过调用msvc100的“新”运算符来查看它。
进一步比较客户端PC上的minidump和我的PC,我发现我的PC调用了一个偏移量为0x0254的函数到地址表中。在客户端PC上,代码试图调用偏移量为0x8254的函数。
更令人困惑的是,此偏移量不是来自寄存器或其他内存位置。偏移量是反汇编中的常量。因此,反汇编看起来像:
call dword ptr [ 0x50018254 ]
不喜欢:
call dword ptr [ edx ]
有谁知道这可能会发生什么?
答案 0 :(得分:0)
这是一个单一的翻转:
0x0254 = 0b0000001001010100
0x8254 = 0b1000001001010100
可能是腐败的记忆,腐败的磁盘,来自太阳的伽马射线......?
如果这个特定情况可以重现并且它们的磁盘二进制文件与你的匹配,我会进一步调查。如果它不是特别可重现的,我鼓励客户运行一些机器诊断。
答案 1 :(得分:0)
多数民众赞成在我看来肯定是硬件错误,主要是内存错误。正如@Hostile_Fork指出的那样,只是有点翻转。
你的记忆是否有ECC功能?它它做到了,确保启用。我会通过memtest86传递一个老化的内存测试来看看会发生什么,我打赌你的内存芯片有问题,看起来不像是一个bug。