Code
//deadlock_debug.cpp: Defines the entry point of the console application. //#include"stdafx.h"#include"windows.h"#include<process.h>//All the thread must get all of critial_section//Classic Deadlockcritical_section Gcritsecfirst; Critical_section Gcritsecsecond; critical_section gcritsecthird;unsigned __stdcall Thread1func (void*dummy) {printf ("Enter Thread 1 \ n"); EnterCriticalSection (&Gcritsecthird); {Sleep ( the); EnterCriticalSection (&Gcritsecfirst); EnterCriticalSection (&Gcritsecsecond); LeaveCriticalSection (&Gcritsecsecond); LeaveCriticalSection (&gcritsecfirst);} LeaveCriticalSection (&gcritsecthird);p rintf ("Exit thread func 1 \ n");return 1;} unsigned __stdcall Thread2func (void*dummy) {printf ("Enter Thread 2 \ n"); EnterCriticalSection (&Gcritsecfirst); EnterCriticalSection (&Gcritsecsecond); {Sleep ( -); EnterCriticalSection (&Gcritsecthird); Sleep ( the); LeaveCriticalSection (&gcritsecthird);} LeaveCriticalSection (&Gcritsecsecond); LeaveCriticalSection (&gcritsecfirst);p rintf ("Exit thread func 2 \ n");return 1;}int_tmain (intARGC, _tchar*argv[]) {Unsigned threadid;initializecriticalsection (&Gcritsecfirst); InitializeCriticalSection (&gcritsecsecond); InitializeCriticalSection (&gcritsecthird); _beginthreadex (NULL,0, &thread1func, NULL,0, &ThreadID); _beginthreadex (NULL,0, &thread2func, NULL,0, &ThreadID); while(1);return 0;}
This is a classic deadlock, open two threads, a 123 in order to take the lock, a 321 order to lock, each other waiting for the other's lock and do not release their hands of the lock. (Here the lock also refers to CriticalSection)
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
开启WINDBG 附加死锁进程,查看 0:003> ~* kv
0 Id: 2b8.2f0 Suspend: 1 Teb: 7ffdf000 Unfrozen ChildEBP RetAddr Args to Child WARNING: Stack unwind information not available. Following frames may be wrong. 0012ff6c 0042e346 00000001 003c30b8 003c3168 Deadlock_Debug+0x2d85c 0012ffb8 0042e21f 0012fff0 7c816d4f 0007da50 Deadlock_Debug+0x2e346 0012ffc0 7c816d4f 0007da50 7c92e1fe 7ffd9000 Deadlock_Debug+0x2e21f 0012fff0 00000000 0042b523 00000000 78746341 kernel32!BaseProcessStart+0x23 (FPO: [Non-Fpo])
1 Id: 2b8.1e0 Suspend: 1 Teb: 7ffde000 Unfrozen ChildEBP RetAddr Args to Child 0059fe00 7c92e9c0 7c93901b 00000030 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) 0059fe04 7c93901b 00000030 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc (FPO: [3,0,0]) 0059fe8c 7c92104b 004944f0 0042d5e0 004944f0 ntdll!RtlpWaitForCriticalSection+0x132 (FPO: [1,26,4]) 0059fe94 0042d5e0 004944f0 57565554 5b5a5958 ntdll!RtlEnterCriticalSection+0x46 (FPO: [1,0,0]) WARNING: Stack unwind information not available. Following frames may be wrong. 0059ff6c 0042e123 00000000 2d7b25f9 57565554 Deadlock_Debug+0x2d5e0 0059ffa8 0042e094 00000000 0059ffec 7c80b50b Deadlock_Debug+0x2e123 0059ffb4 7c80b50b 003c2c20 57565554 5b5a5958 Deadlock_Debug+0x2e094 0059ffec 00000000 0042dff0 003c2c20 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo])
2 Id: 2b8.1e4 Suspend: 1 Teb: 7ffdd000 Unfrozen ChildEBP RetAddr Args to Child 0069fe00 7c92e9c0 7c93901b 00000034 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) 0069fe04 7c93901b 00000034 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc (FPO: [3,0,0]) 0069fe8c 7c92104b 004944c0 0042d714 004944c0 ntdll!RtlpWaitForCriticalSection+0x132 (FPO: [1,26,4]) 0069fe94 0042d714 004944c0 57565554 5b5a5958 ntdll!RtlEnterCriticalSection+0x46 (FPO: [1,0,0]) WARNING: Stack unwind information not available. Following frames may be wrong. 0069ff6c 0042e123 00000000 2d4b25f9 57565554 Deadlock_Debug+0x2d714 0069ffa8 0042e094 00000000 0069ffec 7c80b50b Deadlock_Debug+0x2e123 0069ffb4 7c80b50b 003c2e60 57565554 5b5a5958 Deadlock_Debug+0x2e094 0069ffec 00000000 0042dff0 003c2e60 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo])
# 3 Id: 2b8.948 Suspend: 1 Teb: 7ffdc000 Unfrozen ChildEBP RetAddr Args to Child 0038ffc8 7c9707a8 00000005 00000004 00000001 ntdll!DbgBreakPoint (FPO: [0,0,0]) 0038fff4 00000000 00000000 00000000 00000000 ntdll!DbgUiRemoteBreakin+0x2d (FPO: [Non-Fpo])
//////////////////////////////////////////////////// 在切换到线程2 1进行观察 可以看到均是在等待CriticalSection 0:003> ~2 kv ChildEBP RetAddr Args to Child 0069fe00 7c92e9c0 7c93901b 00000034 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) 0069fe04 7c93901b 00000034 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc (FPO: [3,0,0]) 0069fe8c 7c92104b 004944c0 0042d714 004944c0 ntdll!RtlpWaitForCriticalSection+0x132 (FPO: [1,26,4]) 0069fe94 0042d714 004944c0 57565554 5b5a5958 ntdll!RtlEnterCriticalSection+0x46 (FPO: [1,0,0]
0:003> ~1 kv ChildEBP RetAddr Args to Child 0059fe00 7c92e9c0 7c93901b 00000030 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) 0059fe04 7c93901b 00000030 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc (FPO: [3,0,0]) 0059fe8c 7c92104b 004944f0 0042d5e0 004944f0 ntdll!RtlpWaitForCriticalSection+0x132 (FPO: [1,26,4]) 0059fe94 0042d5e0 004944f0 57565554 5b5a5958 ntdll!RtlEnterCriticalSection+0x46 (FPO: [1,0,0]) ////////////////////////////////////////////// 使用!LOCKS指令查看当前的锁 0:003> !locks
CritSec Deadlock_Debug+944f0 at 004944f0 LockCount 1 RecursionCount 1 OwningThread 1e4 EntryCount 1 ContentionCount 1 *** Locked CritSec Deadlock_Debug+944d8 at 004944d8 LockCount 0 RecursionCount 1 OwningThread 1e4 EntryCount 0 ContentionCount 0 *** Locked
CritSec Deadlock_Debug+944c0 at 004944c0 LockCount 1 RecursionCount 1 OwningThread 1e0 EntryCount 1 ContentionCount 1 *** Locked
|
Can be judged by the lock and the owner of the lock and the locking condition of the thread waiting.
Thread number 1E4 is the lock that thread 2 waits for 004944c0 (view based on the Rtlentercriticalsection function portion of the stack)
0069fe94 0042d714 004944c0 57565554 5b5a5958 ntdll! RTLENTERCRITICALSECTION+0X46 (FPO: [1,0,0])
And 004844c0 's lock by thread number 1E0 is thread 1 holding
and thread number 1e0 is thread 1 waiting for the lock on the 004944f0. The cable number 1E4 holds
0059fe94 0042d5e0 004944f0 57565554 5b5a5958 ntdll! RTLENTERCRITICALSECTION+0X46 (FPO: [1,0,0])
Dead Lock!!!
Find out the reason is good to fix.