1

我们正在用 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>

4

0 回答 0