2011-04-05 25 views
2

我在我的主要結束時遇到了一個奇怪的訪問衝突,其原因是我遇到了一些困難。_DebugHeapDelete在終止時訪問衝突

Xdebug的

 // TEMPLATE FUNCTION _DebugHeapDelete 
template<class _Ty> 
    void __CLRCALL_OR_CDECL _DebugHeapDelete(_Ty *_Ptr) 
    { // delete from the debug CRT heap even if operator delete exists 
    if (_Ptr != 0) 
     { // worth deleting 
     _Ptr->~_Ty(); 
     // delete as _NORMAL_BLOCK, not _CRT_BLOCK, since we might have 
     // facets allocated by normal new. 
     free(_Ptr); // **ACCESS VIOLATION** 
     } 
    } 

堆棧跟蹤:

當關閉我的應用程序在下面得到一個訪問衝突

> msvcp100d.dll!std::_DebugHeapDelete<void>(void * _Ptr) Line 62 + 0xa bytes C++ 
    msvcp100d.dll!std::numpunct<char>::_Tidy() Line 190 + 0xc bytes C++ 
    msvcp100d.dll!std::numpunct<char>::~numpunct<char>() Line 122 C++ 
    msvcp100d.dll!std::numpunct<char>::`scalar deleting destructor'() + 0x11 bytes C++ 
    msvcp100d.dll!std::_DebugHeapDelete<std::locale::facet>(std::locale::facet * _Ptr) Line 62 C++ 
    msvcp100d.dll!std::_Fac_node::~_Fac_node() Line 23 + 0x11 bytes C++ 
    msvcp100d.dll!std::_Fac_node::`scalar deleting destructor'() + 0x11 bytes C++ 
    msvcp100d.dll!std::_DebugHeapDelete<std::_Fac_node>(std::_Fac_node * _Ptr) Line 62 C++ 
    msvcp100d.dll!_Fac_tidy() Line 41 + 0x9 bytes C++ 
    msvcp100d.dll!std::_Fac_tidy_reg_t::~_Fac_tidy_reg_t() Line 48 + 0xe bytes C++ 
    msvcp100d.dll!std::`dynamic atexit destructor for '_Fac_tidy_reg''() + 0xf bytes C++ 
    msvcp100d.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 415 C 
    msvcp100d.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 526 + 0x11 bytes C 
    msvcp100d.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 476 + 0x11 bytes C 

任何人有任何想法,以什麼可能會導致這樣?

我讀了一些關於被緩存的方面的信息,不確定這些信息是否相關?

+0

發佈您正在做的最小示例代碼。 – Mahesh 2011-04-05 22:44:59

+0

@Mahesh:我很想去,但我有超過1萬行代碼。並且由於問題發生在main的結尾(我在main的return語句處放置了一個斷點,在這一點上沒有發生任何問題),但我不知道哪些行可能與問題相關。 – ronag 2011-04-05 22:49:05

+0

我想我的問題是,如果有人知道什麼樣的錯誤可能會導致此失敗? – ronag 2011-04-05 22:51:54

回答

2

內存損壞錯誤可以(很明顯)導致這種(和其他許多種)失敗。

您是否嘗試過使用valgrind(memcheck)或Rational Purify來對付它?它可能會報告這個問題(如果這是你第一次在你的代碼基礎上進行這樣的檢查,可能會埋藏在很多其他的信息中),你仍然想要設計一個最小的'main'實現,行爲下的內存和邊界檢查運行

$ 0.02

PS。爲了以防萬一,內存損壞漏洞通常是由非關聯陳舊指針出現

  • (免費後/刪除)
  • 通過寫作超過分配的緩衝區
  • 通過釋放/刪除以前的指針(主要是不好的所有權跟蹤的症狀)
4

如果覆蓋operator new和使用你可能會遇到同樣的原因是我的結束。 代碼可能會像

#include "yournew" //override new declare .. 
#include "fstream" 
std::fstream f 
f.open(...) 

因爲iostream都是模板,這樣新_Fac_node的使用new操作符。但退出時,您的內存池可能在_Fac_tidy之前退出,然後當〜_Fac_tidy()運行時,程序崩潰。

1

我相信你遇到了我在MSVC10運行時所做的相同的bug。據我的理解,這是由DLL在卸載時刪除全局方面,然後在進程結束時再次刪除時造成的。如果您將所有內容靜態鏈接,則不會發生。它也不會發生在MSVC9中,無論是靜態還是共享鏈接。

1

第一個被接受的答案是正確的,但它並沒有顯示確切的原因,因此也沒有顯示修正方法。根據調用堆棧列出的部分,我遇到了與VC++ 8(MS VS 2005)相同的問題,但在不同的情況下:我的CLR DLL在代碼的同一點引起了AV。

從列出的調用堆棧可以看出,通常編譯爲msvc * .dll的代碼<xdebug>被調用,但此時_Ptr已經有錯誤的值。因此,有一些代碼已經釋放了該指針下的對象,或者設置了一個退出鉤子來釋放未初始化的對象。

如果定義了_STATIC_CPPLIB,則可以將<xdebug>代碼編譯到加載到應用程序進程中的其他模塊中。然後,可以在msvcp100d.dll中的另一個之前調用這些模塊的一個退出過程,因此通常可以釋放該方面對象。在我的情況下,定義了_STATIC_CPPLIB,這兩個模塊(exe和clr dll)都已編譯完成。

VC++解決方案8,9

檢查「命令行」部分中存在的最終編譯器選項/D "_STATIC_CPPLIB"。未定義_STATIC_CPPLIB並重新編譯受影響的模塊會在程序終止時修復AV。

_STATIC_CPPLIB

對於VC++9 _STATIC_CPPLIB注意,在MSDN,還有就是注意,

_STATIC_CPPLIB預處理器定義和 /clr/clr:pure編譯器選項的組合,不支持。

對於較高的VS版本,_STATIC_CPPLIB沒有提及。 對於更高的VS版本和特別是VS 10,我想代碼依賴於_STATIC_CPPLIB仍然存在。在TS的情況下,如果_STATIC_CPPLIB仍然用於任何包含<string>的TU的編譯器選項或包括<locale>在內的其他頭文件,則此不正確的組合可能會導致AV。