_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
有人对可能导致此问题的原因有任何想法吗?
我读到一些有关缓存方面的内容,不确定这是否相关?
I'm getting a weird access violation at the end of my main whose cause I'm having some difficulties finding.
When shutting down my application I get an access violation in the following:
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**
}
}
Stack trace:
> 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
Anyone got any ideas as to what might cause this?
I read something about facets being cached not sure if thats related?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您覆盖 new 运算符并使用您可能会遇到与我相同的原因。
代码可能是这样的
,因为 iostream 是模板,所以 _Fac_node 的 new 使用你的运算符 new。但是当退出时,你的内存池可能会在_Fac_tidy之前退出,然后当~_Fac_tidy()运行时,程序崩溃了。
If you override the operator new and use you may meet the same cause as me.
the code may be like
because the iostream is template so the new of _Fac_node use your operator new. but when exit, your memory pool may exit before _Fac_tidy, then when ~_Fac_tidy() run,the program crashed.
内存损坏错误可能(显然)导致这种(以及许多其他类型)故障。
您是否尝试过使用 valgrind (memcheck) 或 Rational Purify 来解决这个问题?它可能会报告问题(如果这是您第一次对代码库运行此类检查,则可能会隐藏在大量其他信息中)。您仍然想要设计一个最小的“主” ' 表现出在内存和边界检查器下运行的行为
$0.02
PS,以防万一,内存损坏错误通常是
Memory corruption bugs can (obviously) cause this (and many other kinds) of failure.
Have you tried using valgrind (memcheck) or Rational Purify against this? It will probably report the problem (possibly buried in a whole lot of other information if this would be the first time you ran such a check on your code base. You will still want to devise a minimal 'main' implementation that exhibits the behaviour to run under a memory and bounds checker
$0.02
PS. just in case, memory corruption bugs usually arise
第一个被接受的响应是正确的,但它没有准确地显示原因以及修复它的方法。根据调用堆栈的列出部分,我在 VC++8 (MS VS 2005) 中遇到了同样的问题,但情况不同:我的 CLR DLL 在代码的同一点导致了 AV。
从列出的调用堆栈中可以看出,正常情况下编译成 msvc*.dll 的
代码被调用,但此时_Ptr
已经出现错误价值。因此,有一些代码要么已经释放了该指针下的对象,要么设置了退出挂钩来释放未初始化的对象。如果
_STATIC_CPPLIB
< /a> 被定义后,
代码可以被编译到加载到应用程序进程中的其他模块中。然后,这些模块的一个退出过程可以在 msvcp100d.dll 中的另一个退出过程之前被调用,因此可以正常释放构面对象。就我而言,定义了 _STATIC_CPPLIB 后,两个模块(exe 和 clr dll)都已编译。Solution for VC++8,9
检查“命令行”部分中的最终编译器选项是否存在
/D "_STATIC_CPPLIB"
。取消定义_STATIC_CPPLIB
并重新编译受影响的模块可修复程序终止时的 AV。Note on
_STATIC_CPPLIB
对于 VC++9
_STATIC_CPPLIB< /code>
,在 MSDN 上,有这样的注释:
并且没有提及更高 VS 版本的
_STATIC_CPPLIB
。对于更高的 VS 版本,特别是 VS 10,我认为依赖于 _STATIC_CPPLIB 的代码仍然存在。在 TS 的情况下,如果
_STATIC_CPPLIB
仍然在包含
或其他包含
的标头的 TU 的编译器选项中使用code>,这种不正确的组合可能会导致 AV。The first, accepted, response is correct, but it does not show exactly the reason and hence the way of fixing it. According to the listed part of the call stack, I've encountered into the same problem with VC++8 (MS VS 2005) but in the different case: my CLR DLL caused AV at the same point of the code.
From the listed call stack it is seen that the code of
<xdebug>
that is normally compiled into msvc*.dll is called but at that moment the_Ptr
already has wrong value. Hence, there is some code that either already freed the object under this pointer or set an exit hook to free the uninitialized object.If
_STATIC_CPPLIB
was defined, the<xdebug>
code could be complied into other modules that are loaded into the application process. Then, one exit procedure of those modules could be called prior to another one in msvcp100d.dll and thus could normally free the facet object. In my case, with_STATIC_CPPLIB
defined, both the modules (exe and clr dll) were compiled.Solution for VC++8,9
Check the final compiler options in the "Command Line" section for the presence
/D "_STATIC_CPPLIB"
. Undefining_STATIC_CPPLIB
and recompiling affected modules fixes the AV at program termination.Note on
_STATIC_CPPLIB
For VC++9
_STATIC_CPPLIB
, at MSDN, there is the note thatAnd there are no mentions on
_STATIC_CPPLIB
for higher VS versions.For higher VS versions and VS 10 in particular, I suppose that the code dependent on
_STATIC_CPPLIB
still exists. In the TS's case, if_STATIC_CPPLIB
is still used in the compiler options of any TU that includes<string>
or other headers including<locale>
, this improper combination could lead to AV.我相信您也遇到了同样的bug 我在 MSVC10 运行时中遇到了这个问题。据我了解,这是由于运行时在 DLL 卸载时删除全局 Facet,然后在进程结束时再次删除它造成的。如果您静态链接所有内容,则不会发生这种情况。在 MSVC9 中也不会发生这种情况,无论是静态链接还是共享链接。
I believe you're experiencing the same bug I did in the MSVC10 runtime. To my understanding, it is caused by the runtime deleting a global facet when a DLL unloads, and then deleting it again when the process ends. If you link everything statically, it shouldn't happen. It also won't happen in MSVC9, either with static or shared linkage.
太长了;在我的代码中使用了自定义分配类,该类跟踪使用 new 创建和删除的所有内存。由于此类的关闭函数是在 Microsoft 的 CRT 清理并释放由此创建的任何内存之前调用的。我只是在代码中覆盖了 locale0.cpp 中的 CRT 代码,并注释掉了循环以释放 CRT 内存。因为它已经被我的班级删除了。
应用程序正在尝试
删除
它为wostreambuf* 和ostreambuf*
创建的内存,在我的实例中作为lambda 函数
的一部分。它创建了存储在 __PURE_APPDOMAIN_GLOBAL static _Fac_node* _Fac_head = nullptr; 中的内存,并在程序执行结束后将其删除。通过从
_Fac_tidy_reg_t
调用析构函数~_Fac_tidy_reg_t()
。因为在我的应用程序中,我重写了 new 和 delete 函数并自己管理内存。程序在执行结束时会自动
删除
它使用的任何内存,因此当 CRT 调用此~_Fac_tidy_reg_t()
析构函数时,内存已经被释放,但不一定“ nullptr刚刚标记为未使用。当
~_Fac_tidy_reg_t()尝试循环
_Fac_head`时,内存已被释放,因此会导致异常。要解决此问题,我只需
重载 ~_Fac_tidy_reg_t() 并注释掉运行循环以
删除
已删除
内存地址的代码。TLDR; used a custom Allocation class in my code which tracks all memory crated and deleted using new. Since the shutdown function for this class is called before Microsoft's CRT clean up and frees any memory created by this. I simply overrode the CRT code in locale0.cpp in my code, and commented out the loop to free CRT memory. As it's already deleted by my class.
The application is attempting to
delete
memory it created forwostreambuf* and ostreambuf*
., in my instance as part of alambda function
.It created the memory which got stored in
__PURE_APPDOMAIN_GLOBAL static _Fac_node* _Fac_head = nullptr;
to be deleted after execution of the program ends. By calling the destructor~_Fac_tidy_reg_t()
from_Fac_tidy_reg_t
.Since in my application i override the
new
anddelete
functions and manage the memory myself. The program at the end of execution automaticallydelete
s any memory it used, so when the CRT calls this~_Fac_tidy_reg_t()
destructor the memory is already freed, however not necessarily "nullptrjust marked as unsed. When
~_Fac_tidy_reg_t()attempts to cycle through the
_Fac_head` the memory is already freed and therefore causes a exception.To solve this i simply
overload ~_Fac_tidy_reg_t()
and commented out the code to run the loop todelete
the alreadydelete
d memory address's.