2011-02-17 52 views
2

我们有一个测试用例,它会崩溃我们的大型基于MFC的应用程序,并出现堆损坏错误。解释App验证器输出:堆损坏或将堆栈地址误解为堆地址?

我打开页面堆使用应用程序验证程序的问题的DLL(翻转整个过程堆是不可行的其他原因,不幸的是。)验证人没有给我们比我们更多的信息已经有了;它在原始崩溃的同一时刻触发。

现在我有两个相互竞争的理论。你认为哪种理论更可能是正确的,你的下一步将会是什么?

  1. 这确实是堆腐败。验证者没有捕获原始损坏,因为它发生在另一个DLL中。我们应该尝试激活更多DLL的验证程序,并确定哪些代码损坏了堆。
  2. 堆很好;问题是我们将堆栈地址视为堆地址。我们应该进一步研究这个调用堆栈中的代码,以弄清楚什么是错误的。

因为参数free()看起来像一个堆栈地址,所以我倾向于#2,但到目前为止没有人提出解释如何实现这一点。

这是调用堆栈的一个片段。 MyString是CString的简单包装。 MyAppDll是设置为使用页堆的DLL。

msvcr90.dll!free(void * pBlock=0x000000000012d6e8) Line 110 
mfc90u.dll!ATL::CStringT > >::~CStringT > >() Line 1011 + 0x1e bytes 
MyStringDll.dll!MyString::~MyString() Line 59 
MyAppDll.dll!doStuffWithLotsOfStringInlining(MyClass* input=0x000000000012d6d0) Line 863 + 0x26 bytes

这里是免费的()堆栈帧内部寄存器:

 
RAX = 0000000000000000 RBX = 000000000012D6E8 RCX = 0000000000000000 
RDX = 0000000000000000 RSI = 000000000012D6D0 RDI = 00000000253C1090 
R8 = 0000000000000000 R9 = 0000000000000000 R10 = 0000000000000000 
R11 = 0000000000000000 R12 = 000000000012D7D0 R13 = 000007FFFFC04CE0 
R14 = 0000000025196600 R15 = 0000000000000000 RIP = 00000000725BC7BC 
RSP = 000000000012D570 RBP = 000007FFF3670900 EFL = 00000000 

而这里的应用程序验证信息:

 
VERIFIER STOP 0000000000000010: pid 0x1778: Corrupted start stamp for heap block. 

    00000000083B1000 : Heap handle used in the call. 
    000000006DD394E8 : Heap block involved in the operation. 
    54D32858A8747589 : Size of the heap block. 
    000000005E33BA8D : Corrupted stamp value. 

回答

1

我想你的字符串或用户的是/正在溢出/下溢字符串的缓冲区,可能是字符串旁边的字段,然后尝试释放。

您的RSP是12D570,与您试图释放的东西相距94个四边形(整数),所以在这之间的某个地方,缓冲区出现了一些不好的情况。

验证您是否正在执行任何不安全的字符串操作,并且您正在正确地阅读将缓冲区/字符串传递到正在使用的DLL的文档。

如果您想要更准确的答案,您可能需要更多代码。

+0

谢谢,这是我正在寻找的答案。不幸的是,这里只涉及太多的代码来提供完整的图片,我不认为简短的摘录会有帮助。 – Dewb 2011-02-17 23:34:56