2018년 3월 20일 화요일

참고 Deadlock으로 freeze된 상황 찾기

2010. 8. 3. 12:58

다음의 내용은 Quad Dimensions에서 Debugging 교육 자료로 만든 내용입니다.
본부장 
가져 가실때는 이 정보 남겨 주시는것이 예의 겠지요 ^^




참고 Deadlock으로 freeze된 상황 찾기


첨부된 소스의 errTestDeadLock()함수를 실행 시키면 dead lock이 발생된다.
실행시키면 잠시 후 *BUSY* Debuggee is running… 이라고 표시되고 멈춘 상태를 볼 수 있다.

Ctrl-Break 를 눌러서 일시 정지를 시킨다.
명령어를 이용해 현재 작동중인 thread목록을 보면 아래와 같다.
0:003> ~
   0  Id: 2f4.e30 Suspend: 1 Teb: 7ffdf000 Unfrozen
   1  Id: 2f4.1374 Suspend: 1 Teb: 7ffde000 Unfrozen
   2  Id: 2f4.1070 Suspend: 1 Teb: 7ffdd000 Unfrozen
.  3  Id: 2f4.4e0 Suspend: 1 Teb: 7ffdc000 Unfrozen   ( . 표시된 것이 현재 active thread 이다. )

위와 같이 멈춘 상황에서는 각각 thread별로 call stack를 확인해 봐야 한다.
~번호 kb 명령어를 이용해 thread별로 확인해 본다또는 ~* kb 명령어로 모든 thread출력

0:003> ~0 kb
ChildEBP RetAddr  Args to Child             
… 중략 
0012ff40 00420457 00000001 01331a60 01331ad8 Timetest!main+0x1f
0012ff88 77441174 7ffd4000 0012ffd4 7790b3f5 Timetest!__tmainCRTStartup+0xfb
0012ff94 7790b3f5 7ffd4000 93c140e8 00000000 kernel32!BaseThreadInitThunk+0xe
0012ffd4 7790b3c8 004204ae 7ffd4000 00000000 ntdll!__RtlUserThreadStart+0x70
0012ffec 00000000 004204ae 7ffd4000 00000000 ntdll!_RtlUserThreadStart+0x1b

0:003> ~1 kb
ChildEBP RetAddr  Args to Child             
0132fdc0 778f5e6c 778dfc72 00000044 00000000 ntdll!KiFastSystemCallRet
0132fdc4 778dfc72 00000044 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
0132fe28 778dfb56 00000000 00000000 013312c0 ntdll!RtlpWaitOnCriticalSection+0x13e
0132fe50 004043ec 00446560 cfe17652 00000000 ntdll!RtlEnterCriticalSection+0x150
0132ff38 0041a946 01333df0 01333df0 0132ff80 Timetest!SDList::Lock+0x6c
0132ff48 00420058 00000000 cfe176ea 00000000 Timetest!testThread3+0x36
0132ff80 004200f4 0132ff94 77441174 013312c0 Timetest!_callthreadstart+0x1b
0132ff88 77441174 013312c0 0132ffd4 7790b3f5 Timetest!_threadstart+0x76
0132ff94 7790b3f5 013312c0 92e140e8 00000000 kernel32!BaseThreadInitThunk+0xe
0132ffd4 7790b3c8 0042007e 013312c0 00000000 ntdll!__RtlUserThreadStart+0x70
0132ffec 00000000 0042007e 013312c0 00000000 ntdll!_RtlUserThreadStart+0x1b

0:003> ~2 kb
ChildEBP RetAddr  Args to Child             
0143fdbc 778f5e6c 778dfc72 00000048 00000000 ntdll!KiFastSystemCallRet
0143fdc0 778dfc72 00000048 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
0143fe24 778dfb56 00000000 00000000 013314f0 ntdll!RtlpWaitOnCriticalSection+0x13e
0143fe4c 004043ec 00446578 cf90765e 00000000 ntdll!RtlEnterCriticalSection+0x150
0143ff34 0041a9c6 00000000 013317a0 00000001 Timetest!SDList::Lock+0x6c
0143ff48 00420058 00000000 cf9076ea 00000000 Timetest!testThread4+0x36
0143ff80 004200f4 0143ff94 77441174 013314f0 Timetest!_callthreadstart+0x1b
0143ff88 77441174 013314f0 0143ffd4 7790b3f5 Timetest!_threadstart+0x76
0143ff94 7790b3f5 013314f0 929040e8 00000000 kernel32!BaseThreadInitThunk+0xe
0143ffd4 7790b3c8 0042007e 013314f0 00000000 ntdll!__RtlUserThreadStart+0x70
0143ffec 00000000 0042007e 013314f0 00000000 ntdll!_RtlUserThreadStart+0x1b

0:003> ~3 kb
ChildEBP RetAddr  Args to Child             
0153ff58 7794d279 928040b4 00000000 00000000 ntdll!DbgBreakPoint
0153ff88 77441174 00000000 0153ffd4 7790b3f5 ntdll!DbgUiRemoteBreakin+0x3c
0153ff94 7790b3f5 00000000 928040e8 00000000 kernel32!BaseThreadInitThunk+0xe
0153ffd4 7790b3c8 7794d23d 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
0153ffec 00000000 7794d23d 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b

0번은 main thread이고 , 1 2번에서 RtlEnterCriticalSection()이 호출되는 것으로 보아 여기서 dealock이 걸린 것임을 유추 할 수 있다.

해당 함수들을 역어셈블 해보면 내용이 더 쉽게 눈에 들어 온다.



0:003> uf Timetest!testThread3
… 중략 
209 0041a932 b990654400      mov     ecx,offset Timetest!sd3 (00446590)
209 0041a937 e8449afeff      call       Timetest!SDList::Lock (00404380)
210 0041a93c b958664400      mov     ecx,offset Timetest!sd4 (00446658)
210 0041a941 e83a9afeff      call       Timetest!SDList::Lock (00404380)

0:003> uf Timetest!testThread4
… 중략 
229 0041a9b2 b958664400      mov     ecx,offset Timetest!sd4 (00446658)
229 0041a9b7 e8c499feff      call       Timetest!SDList::Lock (00404380)
230 0041a9bc b990654400      mov     ecx,offset Timetest!sd3 (00446590)
230 0041a9c1 e8ba99feff      call       Timetest!SDList::Lock (00404380)

내용을 보면 전형적인 deadlock임을 이해 할 수 있을 것이다.


제일 처음 부분에서 ~ 명령어를 사용했을 때 4개의 thread가 모두 suspend 된것으로 나오는데 , 이것은 dos console 모드에서 작업을 해서 그렇고 window application이라면 정지된 thread suspend로 나오기 때문에 조금 더 이해가 쉽다.

댓글 없음:

댓글 쓰기