我们正在用 Python、Qt4(目前为 4.6.1)和 .NET(出于集成原因)编写一个混合模式应用程序。
现在,当应用程序正常存在时,.NET 运行时被卸载,它将 PROCESS_DETACH 感知到所有 DLL。当 QHostInfoLookupManager' detriuctor estrys 线程池时,这似乎会导致崩溃。
有没有办法防止这种情况,除了:
- 终止进程?
- 将 .NET 代码移动到单独的进程以避免 Qt 问题。
当我崩溃时,调用堆栈如下:
python26.dll!1e02edbf()
[Frames below may be incorrect and/or missing, no symbols loaded for python26.dll]
python26.dll!1e078aba()
QtCore.pyd!01971058()
QtCore4.dll!qt_message_output(QtMsgType msgType=QtWarningMsg, const char * buf=0x077526a8) Line 2223 + 0x1c bytes C++
QtCore4.dll!qt_message(QtMsgType msgType=QtWarningMsg, const char * msg=0x671b8464, char * ap=0x0012f1d4) Line 2297 C++
QtCore4.dll!qWarning(const char * msg=0x671b8464, ...) Line 2378 + 0x11 bytes C++
QtCore4.dll!QWaitCondition::~QWaitCondition() Line 156 C++
QtCore4.dll!QThreadPoolPrivate::~QThreadPoolPrivate() + 0xa2 bytes C++
QtCore4.dll!QThreadPoolPrivate::`scalar deleting destructor'() + 0x8 bytes C++
QtCore4.dll!QObject::~QObject() Line 992 + 0x16 bytes C++
QtCore4.dll!QThreadPool::~QThreadPool() Line 430 + 0xf bytes C++
QtNetwork4.dll!QHostInfoLookupManager::~QHostInfoLookupManager() Line 454 + 0x23 bytes C++
QtNetwork4.dll!QHostInfoLookupManager::`scalar deleting destructor'() + 0x8 bytes C++
QtNetwork4.dll!`theHostInfoLookupManager'::`8'::`dynamic atexit destructor for 'cleanup''() + 0x14 bytes C++
QtNetwork4.dll!_CRT_INIT(void * hDllHandle=0x00385f30, unsigned long dwReason=3694344, void * lpreserved=0x00385f08) Line 449 C
QtNetwork4.dll!__DllMainCRTStartup(void * hDllHandle=0x64000000, unsigned long dwReason=0, void * lpreserved=0x00000000) Line 560 + 0x8 bytes C
QtNetwork4.dll!_DllMainCRTStartup(void * hDllHandle=0x64000000, unsigned long dwReason=0, void * lpreserved=0x00000001) Line 510 + 0xe bytes C
ntdll.dll!_LdrpCallInitRoutine@16() + 0x14 bytes
ntdll.dll!_LdrShutdownProcess@0() - 0xfe bytes
kernel32.dll!__ExitProcess@4() + 0x42 bytes
kernel32.dll!7c81cb26()
mscorwks.dll!SafeExitProcess() + 0xb7 bytes
mscorwks.dll!DisableRuntime() - 0x199708 bytes
mscoreei.dll!RuntimeDesc::ShutdownAllActiveRuntimes() + 0x873e bytes
mscoreei.dll!_CorExitProcess@4() + 0x26 bytes
mscoree.dll!_ShellShim_CorExitProcess@4() + 0x94 bytes
msvcr90.dll!__crtCorExitProcess(int status=0) Line 716 C
msvcr90.dll!__crtExitProcess(int status=0) Line 722 + 0x8 bytes C
msvcr90.dll!doexit(int code=0, int quick=0, int retcaller=0) Line 632 C
msvcr90.dll!exit(int code=0) Line 412 + 0xc bytes C
python26.dll!1e030405()
python26.dll!1e02cd93()
python26.dll!1e02e887()
python26.dll!1e02ccba()
MyApp.exe!orz::runPythonFile(const char * file=0x00a203f0, QDir pydir={...}, QString pypath={...}) Line 66 + 0x3e bytes C++
MyApp.exe!orz::the_main(int argc=2, char * * argv=0x003860e0) Line 132 + 0x50 bytes C++
MyApp.exe!main(int argc=2, char * * argv=0x003860e0) Line 152 + 0xd bytes C++
MyApp.exe!_WinMain@16() + 0xb8 bytes
kernel32.dll!_BaseProcessStart@4() + 0x23 bytes
也许有一些我的消息处理,但我不希望从 .net 中卸载 dll。我尝试稍微更改我的日志记录以避免 python 调用,但后来我卡住了“没有运行用户模式线程,应用程序死锁”,似乎与http://qt-project.org/forums/viewthread/20462有关。
ntdll.dll!_KiFastSystemCallRet@0()
ntdll.dll!_NtWaitForSingleObject@12() + 0xc bytes
kernel32.dll!_WaitForSingleObjectEx@12() + 0x8b bytes
kernel32.dll!_WaitForSingleObject@8() + 0x12 bytes
QtCore4.dll!QWaitCondition::wait(QMutex * mutex=0x07ccf200, unsigned long time=4294967295) Line 175 + 0x15 bytes C++
QtCore4.dll!QThreadPoolPrivate::waitForDone() Line 295 + 0x10 bytes C++
QtCore4.dll!QThreadPool::~QThreadPool() Line 429 C++
Qt 不支持 dll 卸载,引用自上面的帖子
“老实说,我不知道如何处理这项任务。我似乎记得看到 Windows 线程会在应用程序退出时消失的情况,但不会向这些线程发出 HANDLE 信号(这意味着如果在句柄上等待,您的应用程序将死锁)。
我很想简单地将其标记为“超出范围”,因为正如 Thiago 所说,我们不测试也不真正支持在加载 Qt 库后从应用程序中卸载它们。”</p>