由于堆损坏,任何提示,C++/msvc6应用程序崩溃?

dav*_*dag 6 windows crash windbg visual-c++ heap-corruption

关于申请

  • 它在Windows XP Professional SP2上运行.
  • 它是使用带有Service Pack 6的Microsoft Visual C++ 6.0构建的.
  • 它是基于MFC的.
  • 它使用几个外部dll(例如Xerces,ZLib或ACE).
  • 它具有很高的性能要求.
  • 它做了很多网络和硬盘I/O,但它也是CPU密集型的.
  • 它有一个异常处理机制,在发生未处理的异常时生成一个小型转储.
  • 更新:它是一个高度多线程的应用程序,我们使用互斥锁来保护并发访问(当然,我们可能在某些地方失败了......)

关于崩溃的事实

  • 它只发生在多处理器/多核机器上以及繁重的工作中.
  • 它经过几个小时的运行后随机发生(我们和我们的客户都没有找到模式).
  • 我们无法在我们的测试实验室重现崩溃.它只发生在一些生产系统上(但总是在多核机器上)
  • 虽然完整的堆栈并不总是相同的,但它总是在同一点崩溃.让我添加崩溃线程的堆栈(使用WinDbg获取,抱歉我们没有符号)
Exception code: c0000005 ACCESS_VIOLATION
Address        : 006a85b9
Access Type    : write
Access Address : 2e020fff
Fault address:  006a85b9 01:002a75b9 C:\MyDir\MyApplication.exe

ChildEBP RetAddr  Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
030af6c8 7c9206eb 77bfc3c9 01a80000 00224bc3 MyApplication+0x2a85b9
030af960 7c91e9c0 7c92901b 00000ab4 00000000 ntdll!RtlAllocateHeap+0xeac (FPO: [Non-Fpo])
030af98c 7c9205c8 00000001 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc (FPO: [3,0,0])
030af9c0 7c920551 01a80898 7c92056d 313adfb0 ntdll!RtlpFreeToHeapLookaside+0x22 (FPO: [2,0,4])
030afa8c 4ba3ae96 000307da 00130005 00040012 ntdll!RtlFreeHeap+0x1e9 (FPO: [Non-Fpo])
030afacc 77bfc2e3 0214e384 3087c8d8 02151030 0x4ba3ae96
030afb00 7c91e306 7c80bfc1 00000948 00000001 msvcrt!free+0xc8 (FPO: [Non-Fpo])
030afb20 0042965b 030afcc0 0214d780 02151218 ntdll!ZwReleaseSemaphore+0xc (FPO: [3,0,0])
030afb7c 7c9206eb 02e6c471 02ea0000 00000008 MyApplication+0x2965b
030afe60 7c9205c8 02151248 030aff38 7c920551 ntdll!RtlAllocateHeap+0xeac (FPO: [Non-Fpo])
030afe74 7c92056d 0210bfb8 02151250 02151250 ntdll!RtlpFreeToHeapLookaside+0x22 (FPO: [2,0,4])
030aff38 77bfc2de 01a80000 00000000 77bfc2e3 ntdll!RtlFreeHeap+0x647 (FPO: [Non-Fpo])
7c92056d c5ffffff ce7c94be ff7c94be 00ffffff msvcrt!free+0xc3 (FPO: [Non-Fpo])
7c920575 ff7c94be 00ffffff 12000000 907c94be 0xc5ffffff
7c920579 00ffffff 12000000 907c94be 90909090 0xff7c94be
*** WARNING: Unable to verify checksum for xerces-c_2_7.dll
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for xerces-c_2_7.dll - 
7c92057d 12000000 907c94be 90909090 8b55ff8b MyApplication+0xbfffff
7c920581 907c94be 90909090 8b55ff8b 08458bec xerces_c_2_7
7c920585 90909090 8b55ff8b 08458bec 04408b66 0x907c94be
7c920589 8b55ff8b 08458bec 04408b66 0004c25d 0x90909090
7c92058d 08458bec 04408b66 0004c25d 90909090 0x8b55ff8b
  • 地址MyApplication + 0x2a85b9对应于对std :: list的erase()的调用.

到目前为止我尝试过的

  • 查看与崩溃结束发生点相关的所有代码.
  • 尝试在我们的测试实验室中启用pageheap,虽然现在没有找到任何有用的东西.
  • 我们已经将std :: list替换为C数组,然后它在代码的其他部分崩溃(尽管它是相关代码,但它不在旧列表所在的代码中).巧合的是,现在它在另一个擦除中崩溃了,虽然这次是std :: multiset.让我复制转储中包含的堆栈:
ntdll.dll!_RtlpCoalesceFreeBlocks@16()  + 0x124e bytes  
ntdll.dll!_RtlFreeHeap@12()  + 0x91f bytes  
msvcrt.dll!_free()  + 0xc3 bytes    
MyApplication.exe!006a4fda()
[Frames below may be incorrect and/or missing, no symbols loaded for MyApplication.exe] 
MyApplication.exe!0069f305()
ntdll.dll!_NtFreeVirtualMemory@16()  + 0xc bytes    
ntdll.dll!_RtlpSecMemFreeVirtualMemory@16()  + 0x1b bytes   
ntdll.dll!_ZwWaitForSingleObject@12()  + 0xc bytes  
ntdll.dll!_RtlpFreeToHeapLookaside@8()  + 0x26 bytes    
ntdll.dll!_RtlFreeHeap@12()  + 0x114 bytes  
msvcrt.dll!_free()  + 0xc3 bytes    
c5ffffff()  
  • (2010年4月12日)我试图启用堆免费检查(使用gflags),但它大大减慢了应用程序的速度......

可能的解决方案(我知道)无法应用

  • "将应用程序迁移到更新的编译器":我们正在努力解决这个问题,但目前还不是解决方案.
  • "启用pageheap(正常或完整)":我们无法在生产计算机上启用pageheap,因为这会严重影响性能.

我想这就是我现在所记得的,如果我忘记了什么,我会尽快添加它.如果您能给我一些提示或提出一些可能的解决方案,请不要犹豫回答!

Mic*_*urr 1

您可以尝试在代码中调用调试堆检查例程,看看是否可以找到更接近源的损坏位置(您正在使用调试 CRT 来追踪此问题,对吧?):