Re: 求教线程退出时的死锁问题

C/C++本地代码调试

求教线程退出时的死锁问题


woodhead 2013-04-26, 17:28 下午

dump分析如下:0号线程在等16号线程,16号线程在等一个临界区,这个临界区被0号线程占着。分析代码,0号线程死锁那会释放等待的线程有点多,不好找到底是等哪个线程出的问题。16号线程退出时等待的临界区到底是什么呢?

ps:_endthreadex程序中没有显式调用,操作系统自己调用的。

0:000> kbn
# ChildEBP RetAddr Args to Child
00 0043df48 76e60816 00000954 00000000 00000000 ntdll!ZwWaitForSingleObject+0x15
01 0043dfb4 76021184 00000954 ffffffff 00000000 KERNELBASE!WaitForSingleObjectEx+0x98
02 0043dfcc 76021138 00000954 ffffffff 00000000 kernel32!WaitForSingleObjectExImplementation+0x75
03 0043dfe0 5cf92cc9 00000954 ffffffff 00000040 kernel32!WaitForSingleObject+0x12

......

0:016> kbn
 # ChildEBP RetAddr  Args to Child             
00 1942fdb4 77368de4 000001e4 00000000 00000000 ntdll!ZwWaitForSingleObject+0x15
01 1942fe18 77368cc8 00000000 00000000 19212988 ntdll!RtlpWaitOnCriticalSection+0x13e
02 1942fe40 7738e861 774320c0 6e0eaaa0 00000000 ntdll!RtlEnterCriticalSection+0x150
03 1942fed8 7738eada 00000000 00000000 1942fef4 ntdll!LdrShutdownThread+0x50
04 1942fee8 5cf92e88 00000000 1942ff2c 5cf92eaa ntdll!RtlExitUserThread+0x2a
05 1942fef4 5cf92ea9 00000000 11f983ea 00000000 AVShow!_endthreadex+0x3c [f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c @ 412]
06 1942ff2c 5cf92f4c 00000000 1942ff44 76023677 AVShow!_callthreadstartex+0x20 [f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c @ 348]
07 1942ff38 76023677 19212988 1942ff84 77369f02 AVShow!_threadstartex+0x82 [f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c @ 326]
08 1942ff44 77369f02 19212988 6e0eabfc 00000000 kernel32!BaseThreadInitThunk+0xe
09 1942ff84 77369ed5 5cf92eca 19212988 00000000 ntdll!__RtlUserThreadStart+0x70
0a 1942ff9c 00000000 5cf92eca 19212988 00000000 ntdll!_RtlUserThreadStart+0x1b

Re: 求教线程退出时的死锁问题


woodhead 2013-04-27, 13:51 下午

搜索了点资料,

DllMain中不当操作导致死锁问题的分析--线程退出时产生了死锁 这篇文章和此dump栈比较像,检查了一下我们的dll,dllmain里面什么都没写,而上层调用的库不是我们写的,不知道是否会有影响。

Re: 求教线程退出时的死锁问题


格蠹老雷 2013-04-27, 15:46 下午
恭喜你遇到著名的LoaderLock死锁,!cs -l寻找哪个线程在占用LoaderLock...

Re: 求教线程退出时的死锁问题


woodhead 2013-04-27, 19:14 下午

这个我上面的没复制全,能看出来,堆栈如下:

0:016> kbn
 # ChildEBP RetAddr  Args to Child             
00 1942fdb4 77368de4 000001e4 00000000 00000000 ntdll!ZwWaitForSingleObject+0x15
01 1942fe18 77368cc8 00000000 00000000 19212988 ntdll!RtlpWaitOnCriticalSection+0x13e
02 1942fe40 7738e861 774320c0 6e0eaaa0 00000000 ntdll!RtlEnterCriticalSection+0x150
03 1942fed8 7738eada 00000000 00000000 1942fef4 ntdll!LdrShutdownThread+0x50
04 1942fee8 5cf92e88 00000000 1942ff2c 5cf92eaa ntdll!RtlExitUserThread+0x2a
05 1942fef4 5cf92ea9 00000000 11f983ea 00000000 AVShow!_endthreadex+0x3c [f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c @ 412]
06 1942ff2c 5cf92f4c 00000000 1942ff44 76023677 AVShow!_callthreadstartex+0x20 [f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c @ 348]
07 1942ff38 76023677 19212988 1942ff84 77369f02 AVShow!_threadstartex+0x82 [f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c @ 326]
08 1942ff44 77369f02 19212988 6e0eabfc 00000000 kernel32!BaseThreadInitThunk+0xe
09 1942ff84 77369ed5 5cf92eca 19212988 00000000 ntdll!__RtlUserThreadStart+0x70
0a 1942ff9c 00000000 5cf92eca 19212988 00000000 ntdll!_RtlUserThreadStart+0x1b


0:016> !cs 774320c0
-----------------------------------------
Critical section   = 0x774320c0 (ntdll!LdrpLoaderLock+0x0)
DebugInfo          = 0x77434360
LOCKED
LockCount          = 0x3
WaiterWoken        = No
OwningThread       = 0x000003a8
RecursionCount     = 0x1
LockSemaphore      = 0x1E4
SpinCount          = 0x00000000

0:016> ~~[0x000003a8]
.  0  Id: e60.3a8 Suspend: 1 Teb: 7efdd000 Unfrozen
      Start: FVMSClient+0x48f4e (00308f4e)
      Priority: 0  Priority class: 32  Affinity: 3

0:016> ~0s;kbn
eax=c0000034 ebx=00000000 ecx=00000000 edx=00000000 esi=00000954 edi=00000000
eip=7734f861 esp=0043df48 ebp=0043dfb4 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
ntdll!ZwWaitForSingleObject+0x15:
7734f861 83c404          add     esp,4
 # ChildEBP RetAddr  Args to Child             
00 0043df48 76e60816 00000954 00000000 00000000 ntdll!ZwWaitForSingleObject+0x15
01 0043dfb4 76021184 00000954 ffffffff 00000000 KERNELBASE!WaitForSingleObjectEx+0x98
02 0043dfcc 76021138 00000954 ffffffff 00000000 kernel32!WaitForSingleObjectExImplementation+0x75
03 0043dfe0 5cf92cc9 00000954 ffffffff 00000040 kernel32!WaitForSingleObject+0x12
04 0043dff4 5cf92c63 00000000 00000080 5cf9109e AVShow!CLS_WaveOutManager::`scalar deleting destructor'+0x3a
05 0043e000 5cf9109e 0000ffff 0521e515 05227433 AVShow!CLS_WaveOutManager::Destroy+0x2f [f:\windows sdk\windows\dsavshow\trunk\source\ds_avshow_dll\waveoutmanager.cpp @ 232]
06 0043e008 0521e515 05227433 0823615a 0c5a2d08 AVShow!AVShowCleanup+0x2e [f:\windows sdk\windows\dsavshow\trunk\source\ds_avshow_dll\dsavshowinterface.cpp @ 45]
......

就是0号线程占着呢,0号和16号互锁,不知道如何往下跟了,0号看不出来哪占着LdrpLoaderLock这个锁了

Re: 求教线程退出时的死锁问题


woodhead 2013-04-27, 19:18 下午

!cs -l 和上面分析一致:也是0号线程占着呢

网上搜索了一下:在"Debug"菜单下----"Exceptions"----"Managed Debugging Assistants"中勾掉"LoaderLock"  这样能解决么?

0:000> !cs -l
-----------------------------------------
DebugInfo          = 0x77434360
Critical section   = 0x774320c0 (ntdll!LdrpLoaderLock+0x0)
LOCKED
LockCount          = 0x3
WaiterWoken        = No
OwningThread       = 0x000003a8
RecursionCount     = 0x1
LockSemaphore      = 0x1E4
SpinCount          = 0x00000000
-----------------------------------------
DebugInfo          = 0x0087bc20
Critical section   = 0x74038ee0 (winmm!TimerThreadCritSec+0x0)
LOCKED
LockCount          = 0x0
WaiterWoken        = No
OwningThread       = 0x00000bf4
RecursionCount     = 0x1
LockSemaphore      = 0x0
SpinCount          = 0x00000000
-----------------------------------------
DebugInfo          = 0x0bf3d060
Critical section   = 0x0440ed40 (SPDecV33!HI_GetVersion+0x1BF70)
LOCKED
LockCount          = 0xFFFFFFFF
WaiterWoken        = Yes
OwningThread       = 0x00000000
RecursionCount     = 0x0
LockSemaphore      = 0x0
SpinCount          = 0x00000000

WARNING: critical section DebugInfo = 0x00000000 doesn't point back
to the DebugInfo found in the active critical sections list = 0x0bf3d060.
The critical section was probably reused without calling DeleteCriticalSection.

Cannot read structure field value at 0x00000002, error 0
ntdll!RtlpStackTraceDataBase is NULL. Probably the stack traces are not enabled.
ntdll!RtlpStackTraceDataBase is NULL. Probably the stack traces are not enabled.

Re: 求教线程退出时的死锁问题


renwotao 2013-04-28, 18:33 下午
你用!locks命令也可以知道这两个线程互锁,应该在DllMain中判断DLL_THREAD_DETACH消息并用DisableLibraryThreadCalls(HMODULE hModule)函数禁止继续发送DLL_THREAD_DETACH消息,具体可参考windows核心编程DLL相关章节

Powered by Community Server Powered by CnForums.Net