Python、Qt4 (現時点では 4.6.1)、および .NET (統合のため) で混合モード アプリケーションを作成しています。
これで、アプリが正常に存在する場合、.NET ランタイムがアンロードされ、すべての DLL に PROCESS_DETACH が送信されます。これは、QHostInfoLookupManager のデストラクタがスレッドプールを試行するときにクラッシュを引き起こすようです。
これを防ぐ方法はありますか?
- プロセスを終了しますか?
- Qt の問題を回避するために、.NET コードを別のプロセスに移動します。
クラッシュしたときの呼び出し履歴は次のとおりです。
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>