我正在使用Visual Studio 2008调试一个(native)多线程的C++应用程序。在看似随机的情况下,我会收到一个"Windows已触发断点..."的错误提示,提示可能是由于堆栈损坏引起的。这些错误不会立即崩溃应用程序,但很可能会在之后的短时间内崩溃。
这些错误的主要问题在于它们只有在损坏已经发生后才会弹出,这使得它们非常难以跟踪和调试,特别是在多线程应用程序中。
什么样的事情可能会导致这些错误?
如何调试它们?
欢迎分享提示、工具、方法和启示。
我正在使用Visual Studio 2008调试一个(native)多线程的C++应用程序。在看似随机的情况下,我会收到一个"Windows已触发断点..."的错误提示,提示可能是由于堆栈损坏引起的。这些错误不会立即崩溃应用程序,但很可能会在之后的短时间内崩溃。
这些错误的主要问题在于它们只有在损坏已经发生后才会弹出,这使得它们非常难以跟踪和调试,特别是在多线程应用程序中。
什么样的事情可能会导致这些错误?
如何调试它们?
欢迎分享提示、工具、方法和启示。
请注意,在我们的本地自制系统(用于嵌入式目标)中,我们将跟踪与大部分其他内容分开,因为运行时开销要高得多。
如果想要真正减缓速度并进行大量的运行时检查,请尝试在Microsoft Visual Studio C++中的main()
或其等效位置的顶部添加以下内容。
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF );
我从检测访问释放的内存中得到一个快速提示,如下:
If you want to locate the error quickly, without checking every statement that accesses the memory block, you can set the memory pointer to an invalid value after freeing the block:
#ifdef _DEBUG // detect the access to freed memory #undef free #define free(p) _free_dbg(p, _NORMAL_BLOCK); *(int*)&p = 0x666; #endif
我发现最有用且每次都有效的工具是代码审核(与好的代码审查人员一起)。
除了代码审查之外,我首先尝试使用Page Heap。Page Heap只需要几秒钟设置时间,运气好的话,可能会找到您的问题所在。
如果Page Heap没有帮助,从微软下载Windows调试工具并学习如何使用WinDbg。很抱歉无法给出更具体的帮助,但调试多线程堆栈破坏不仅仅是科学,更是艺术。在谷歌上搜索“WinDbg堆栈破坏”,您应该可以找到许多相关文章。
您可能还需要检查您是否链接了动态或静态C运行时库。如果您的DLL文件链接到静态C运行时库,则DLL文件具有单独的堆。
因此,如果您在一个DLL中创建一个对象并尝试在另一个DLL中释放它,您将得到与上面看到的相同的消息。这个问题在另一个Stack Overflow问题中被引用,Freeing memory allocated in a different DLL。