2011-04-05 72 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。