【发布时间】:2011-10-10 19:05:48
【问题描述】:
我最近将一个高度线程化的非托管 Win32 C++ 控制台应用程序 (MediaServer.exe) 转换为非托管 Win32 DLL (MediaServer.dll)。我在一个单独的非托管 Win32 控制台应用程序中托管和调试这个 DLL,一切都编译并运行,但大约一分钟后,我会在一个毫无意义的地方随机崩溃,显然是一个损坏的调用堆。这些崩溃发生在各种不同的地方,而且在某种程度上是随机的:但共同点是(显然是损坏的)调用堆栈上总是有各种 libxml2.dll 函数,例如,崩溃可能出现在看起来像这样:
xmlDoc * document = xmlReadMemory(message.c_str(), message.length(), "noname.xml", NULL, 0);
或者像这样:
xmlBufferPtr buffer = xmlBufferCreate();
调用堆栈可能如下所示:
feeefeee()
libxml2.dll!000eeec9()
[Frames below may be incorrect and/or missing, no symbols loaded for libxml2.dll]
libxml2.dll!00131714()
libxml2.dll!001466b6()
libxml2.dll!00146bf9()
libxml2.dll!00146c3c()
libxml2.dll!0018419e()
或者如果你很幸运,像这样:
ntdll.dll!_RtlpWaitOnCriticalSection@8() + 0x99 bytes
ntdll.dll!_RtlEnterCriticalSection@4() - 0x15658 bytes
libxml2.dll!1004dc6d()
[Frames below may be incorrect and/or missing, no symbols loaded for libxml2.dll]
libxml2.dll!10012034()
libxml2.dll!1004b7f7()
libxml2.dll!1003904c()
libxml2.dll!100393a9()
libxml2.dll!10024621()
libxml2.dll!10036e8f()
MediaServer.dll!Controller::parse(std::basic_string<char,std::char_traits<char>,std::allocator<char> > message) Line 145 + 0x20 bytes C++
MediaServer.dll!Controller::receiveCommands() Line 90 + 0x25 bytes C++
MediaServer.dll!MediaServer::processCommands() Line 88 + 0xb bytes C++
MediaServer.dll!MediaServer::processCommandsFunction(void * mediaServerInstance) Line 450 + 0x8 bytes C++
MediaServer.dll!CustomThread::callThreadFunction() Line 79 + 0x11 bytes C++
MediaServer.dll!threadFunctionCallback(void * threadInstance) Line 10 + 0x8 bytes C++
kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
崩溃本身通常会显示类似“MediaServerConsole.exe 中 0x77cd2239 (ntdll.dll) 处的未处理异常:0xC000005:访问冲突写入位置 0x00000014。”
不用说,当我将模块编译为控制台应用程序时,这并没有发生。
在将项目转换为 DLL 时我可能忽略了什么?这不是我以前做过的事情,所以如果我忽略了一些明显的事情,我一点也不感到惊讶。任何帮助表示赞赏。
【问题讨论】:
-
您是否尝试过运行this topic 中的任何建议程序? Purify、Insure++ 等可以帮助您追踪程序中的细微错误。
-
没有,但我现在正在下载 Visual Leak Detector,看看它是否可以查明任何东西。 (大概和 Purify 或 Insure++ 不在一个级别,但它是免费的……)
-
什么原因导致崩溃?访问冲突?我假设是的,因为释放的堆标有 0xFEFEEE。听起来您的堆栈溢出或堆已损坏。另外,您能否检查 DLL 与哪个 CRT 链接(静态/动态、调试/发布)
-
我的常用清单:选择解决方案中的所有项目并验证:C++->优化:优化、偏好大小或速度以及整个程序优化的相同设置。 C++->代码生成:运行时库(在您的情况下为多线程 DLL)和结构成员对齐的相同设置。
-
我会使用 Application Verifier 并启用完整的堆检查。像这样的问题总是很难追踪。