DllMain中不当操作导致死锁问题的分析——线程中调用GetModuleFileName、GetModuleHandle等导致死锁
? ? ? ? 之前的幾篇文章已經(jīng)講解了在DllMain中創(chuàng)建并等待線程導(dǎo)致的死鎖的原因。是否還記得,我們分析了半天匯編才知道在線程中的死鎖位置。如果對(duì)于缺乏調(diào)試經(jīng)驗(yàn)的同學(xué)來(lái)說(shuō),可能發(fā)現(xiàn)這個(gè)位置有點(diǎn)麻煩。那么本文就介紹幾個(gè)例子,它們會(huì)在線程明顯的位置死鎖掉。(轉(zhuǎn)載請(qǐng)指明出于breaksoftware的csdn博客)
? ? ? ? DLL中的代碼依舊簡(jiǎn)單。它獲取叫EVENT的命名事件,然后等待這個(gè)事件被激活。激活的操作自然放在線程中。這次我們不用在DLL中創(chuàng)建線程,而是在Exe中創(chuàng)建。
switch (ul_reason_for_call) {case DLL_PROCESS_ATTACH: {printf("DLL DllGetModuleHandle:\tProcess attach (tid = %d)\n", tid);HANDLE hEvent = CreateEvent( NULL, FALSE, FALSE, L"EVENT" );if ( NULL != hEvent ) {WaitForSingleObject(hEvent, INFINITE);}}break;
? ? ? ? 1 線程中調(diào)用GetModuleFileName死鎖
? ? ? ? 線程函數(shù)是
static DWORD WINAPI ThreadGetModuleFileName(LPVOID h) {HMODULE hDll = (HMODULE)h;WCHAR wszFileName[MAX_PATH] = {0};GetModuleFileName( hDll, wszFileName, MAX_PATH );HANDLE hEvent = CreateEvent( NULL, FALSE, FALSE, L"EVENT" );SetEvent( hEvent );return 0;
}
? ? ? ? 死鎖后,DLL中的死鎖位置和前幾篇文章中一樣,本文之后均不再說(shuō)明。我們關(guān)注線程的堆棧,它是
? ? ? ??我們看到GetModuleFileName在內(nèi)部要調(diào)用LdrLockLoderLock,以進(jìn)入PEB的LoaderLock臨界區(qū)??墒窃撆R界區(qū)被主線程占用著(在調(diào)用DllMain前進(jìn)入臨界區(qū)),主線程還要等待工作線程調(diào)用GetModuleFileName后激活事件才退出,于是就死鎖了。
? ? ? ?2?線程中調(diào)用GetModuleHandle死鎖
? ? ? ? 線程函數(shù)是
static DWORD WINAPI ThreadGetModuleHandle(LPVOID) {Sleep(1000);GetModuleHandle( L"DllWithoutDisableThreadLibraryCalls_A.dll" );HANDLE hEvent = CreateEvent( NULL, FALSE, FALSE, L"EVENT" );SetEvent( hEvent );return 0;
}
? ? ? ? 內(nèi)容我就不說(shuō)明了,我們直接看線程堆棧。
? ? ? ? 我們看到GetModuleHandleW底層還是進(jìn)入了加載器函數(shù)中。并在加載器函數(shù)中進(jìn)入了LdrLockLoderLock,該函數(shù)內(nèi)部要進(jìn)入PEB的LoaderLock臨界區(qū)。可是該臨界區(qū)被主線程占用著(在調(diào)用DllMain前進(jìn)入臨界區(qū)),主線程還要等待工作線程調(diào)用GetModuleHandle后激活事件才退出,于是就死鎖了。
? ? ? ? 3?線程中調(diào)用LoadLibrary死鎖
? ? ? ? 線程函數(shù)
static DWORD WINAPI ThreadLoadLibrary(LPVOID) {Sleep(1000);LoadLibraryW( L"DllWithoutDisableThreadLibraryCalls_A.dll" );HANDLE hEvent = CreateEvent( NULL, FALSE, FALSE, L"EVENT" );SetEvent( hEvent );return 0;
}
? ? ? ? 死鎖后線程堆棧
總結(jié)
以上是生活随笔為你收集整理的DllMain中不当操作导致死锁问题的分析——线程中调用GetModuleFileName、GetModuleHandle等导致死锁的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: DllMain中不当操作导致死锁问题的分
- 下一篇: DllMain中不当操作导致死锁问题的分