gpt4 book ai didi

c++ - 将 C++/Win32 控制台应用程序转换为 DLL 后崩溃

转载 作者:太空宇宙 更新时间:2023-11-04 12:17:49 25 4
gpt4 key购买 nike

我最近将一个高度线程化、非托管的 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 时,有什么我可能忽略的地方吗?这不是我以前做过的事情,所以如果我忽略了一些明显的事情,我一点也不会感到惊讶。感谢您的帮助。

最佳答案

我会说您正在 DLL_THREAD_ATTACH 而不是 DLL_PROCESS_ATTACH 中初始化内存。这种情况会导致您使用在执行线程之外的另一个线程中分配的指针或内存。

另一件事是检查 DLL 依赖项的加载情况。

让我解释一下。当您的 DLL 使用 loadlibrary 加载时,CRT 会进行全局内存分配。这是为了初始化所有全局变量,范围从 C 原始类型开始,默认情况下将它们初始化为零。然后它为结构/类分配内存,并在必要时调用它们的构造函数。

CRT 然后使用 DLL_PROCESS_ATTACH 调用您的 DLLMain 方法以告知您的进程加载的 DLL。对于该进程内的每个线程,CRT 然后使用 DLL_THREAD_ATTACH 调用您的 DLL。

您说过这些是空的,然后调用导出的 C 函数。虽然我可以看到你的 dll 陷入了关键部分。这告诉我,您的全局分配变量和您的线程在 Start() 中分配内存时发生了死锁情况。

我建议将您的初始化代码移动到 Process_Attached 中,这将确保您的所有内存都分配在主进程线程上,类似于应用程序作为单个可执行文件的工作方式。

关于c++ - 将 C++/Win32 控制台应用程序转换为 DLL 后崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6786106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com