|
Internet Explorer의 화면이 멈추는 것과 같은 UI Thread Hang에는 여러 가지 원인이 있겠지만, High CPU가 아니라면, DLL LoaderLock 이나 RPC Calling에 의한 Blocking 그리고, SendMessage 에 의한 Sync Call Blocking 등이 대표적이 아닐까 한다. SendMessage는 Sync Call이기 때문에 Target Window에 Message를 Sending 한 이후에 응답이 올 때 까지는 다음진행이 일어나지 않는 다. 그러므로, Target Window가 Crash가 되거나 Window handle 이 invalid 하다고 해서 정상적인 응답을 받지 못한다면 해당 Thread는 Hang 상태에 있게 된다. 다음은 Debugging시에 볼 수 있는 SendMessage Hang 상태의 예이다. 0번 Thread는 UI Thread로 RPC Call을 하고 있다. 해당 Callstack은 STA COM의 호출에 대한 일반적인 Callstack이다. 만일, Wait 하고 있다면, 문제가 될 수도 있겠지만, 아래를 보면, PeekMessage를 하고 있는 게 그렇게 문제되어 보이진 않는 다. 일단, RPC Call을 하는 대상을 찾아보자. 0:000> kbL ChildEBP RetAddr Args to Child 00122800 77cf93e9 77cf93a8 001228a8 0009010c ntdll!KiFastSystemCallRet 0012282c 77cf9402 001228a8 0009010c 00000400 user32!NtUserPeekMessage+0xc 00122858 769a2700 001228a8 0009010c 00000400 user32!PeekMessageW+0xbc 00122884 769a2744 001228a8 0009010c 00000400 ole32!CCliModalLoop::MyPeekMessage+0x4d 001228c4 769a2bd2 00180010 00000001 00000102 ole32!CCliModalLoop::PeekRPCAndDDEMessage+0x30 001228f4 769a2b76 00180010 00000102 00122ab8 ole32!CCliModalLoop::FindMessage+0x2d 00122928 769a2b33 00122ab8 078c7d30 00000000 ole32!CCliModalLoop::HandleWakeForMsg+0x39 0012293c 769a235c 0012295c 000003e8 0012296c ole32!CCliModalLoop::BlockFn+0x8b 00122964 769b6749 ffffffff 00122a5c 00122994 ole32!ModalLoop+0x5b 00122974 76a91f01 001e8ce8 00122a5c 00000000 ole32!SwitchSTA+0x21 00122994 76a9109a 00122a5c 08f015f4 00122ab8 ole32!CRpcChannelBuffer::SwitchAptAndDispatchCall+0xd1 00122a74 769a2409 08f015f4 00122b88 00122b78 ole32!CRpcChannelBuffer::SendReceive2+0xb9 00122a90 769a23b2 00122b88 00122b78 08f015f4 ole32!CCliModalLoop::SendReceive+0x1e 00122afc 769a0414 08f015f4 00122b88 00122b78 ole32!CAptRpcChnl::SendReceive+0x6f 00122b50 77e04db5 08f015f4 00122b88 00122b78 ole32!CCtxComChnl::SendReceive+0x113 00122b6c 77e04ead 08eb834c 00122bb4 0300002c rpcrt4!NdrProxySendReceive+0x43 00122f48 77e04e42 079e76b0 079e7c5e 00122f80 rpcrt4!NdrClientCall2+0x1fa 00122f68 77d9a453 00000018 00000017 00122fc4 rpcrt4!ObjectStublessClient+0x8b 00122f78 7e500a53 08eb834c 00000009 00000000 rpcrt4!ObjectStubless+0xf 00122fc4 7e7ad460 0af05190 09018834 006148d8 mshtml!CWindow::OnCreate+0xbc 0:000> dd 08f015f4 l8 08f015f4 76972328 769722f8 00000004 00000022 08f01604 079c9330 00000000 001e8ce8 001e9a58 0:000> dd 001e8ce8 l4 001e8ce8 76a96fa0 001e8a18 00000e34 00000d50 <-- e34=PID, d50=TID 27 Id: e34.d50 Suspend: 1 Teb: 7ff91000 Unfrozen Thread 정보를 확인해 보면, 같은 Process내에서의 COM Calling 방식임을 확인할 수 있다. 그리고, 27번 Thread가 해당 STA COM Calling에 대한 Target Thread이다. 그러므로, 27번 Thread의 상태를 확인해 볼 필요가 있다. 0:027> kbL ChildEBP RetAddr Args to Child 0c7ca0ac 77cf94be 77cfd4e4 0006034c 00000282 ntdll!KiFastSystemCallRet 0c7ca0e8 77d0f3cc 006b89e0 00000282 00000006 user32!NtUserMessageCall+0xc 0c7ca108 75122161 0006034c 00000282 00000006 user32!SendMessageA+0x7f 0c7ca15c 7512aabd 00000000 0c7ca188 0c7ca19c MSCTFIME!CKbdOpenCloseEventSink::KbdOpenCloseCallback+0x19c 0c7ca16c 7468b9d6 053dd9d8 0c7ca188 00000000 MSCTFIME!CCompartmentEventSink::OnChange+0x11 . . . 27번 Thread는 SendMessge Call을 하고 있다. 해당 Window handle은 0x6034c 이고, 0x282는 msdn에 찾아본 결과, WM_IME_NOTIFY (winuser.h) Message 이다. 그러므로, 해당 Window Handle이 적절하게 응답 했는지가 관건이다. 그러므로, 일반적으로 hang dump는 2-3차례 수집이 필요하다. 이에 따라 Thread에 변화가 있다면, 이는 hang으로 간주할 수 없지만, 해당 case에서는 임의의 시간이 흘렀음에도 SendMessage Call에 대한 Blocking 상태임을 확인할 수 있었다. (시간이 흐름에 따라 해당 Thread에 대한 변화가 보이지 않았다. ) 그러므로, 이는 UI thread의 Hang을 보여준다고 말할 수 있다.
0:027> dd 006b89e0 006b89e0 0006034c 00000006 e60f6a28 896d9b10 006b89f0 bc7b89e0 000a0000 80000300 00000800 006b8a00 54000080 77160000 00000000 00000000 006b8a10 00000000 bc7b8800 00000000 00000000 006b8a20 000001de 00000192 00000559 0000019f 006b8a30 000001de 00000192 00000559 0000019f 006b8a40 0273b020 bc7d8b78 00000000 bc7b8ad8 <--- WinProc 의 address 006b8a50 00000000 00000000 0273affc 00000000 0:027> u 0273b020 <Unloaded_es_kr.dll>+0x273af0f: 0273b020 c74424041cb07302 mov dword ptr [esp+4],offset <Unloaded_es_kr.dll>+0x273af0b (0273b01c) 0273b028 e98a8bfbff jmp 026f3bb7 0273b02d 0000 add byte ptr [eax],al 0273b02f 0000 add byte ptr [eax],al 0273b031 0000 add byte ptr [eax],al 0273b033 00d1 add cl,dl 0273b035 07 pop es 0273b036 ff ??? 0:027> lm start end module name 00400000 00419000 IEXPLORE (deferred) 01020000 01028000 f_ah (deferred) 01130000 01154000 wsd32 (deferred) . . . 026f0000 02714000 Xxxtttt (export symbols) Xxxtttt.dll 상위의 정보에서 확인 했듯이 SendMessage는 Xxxtttt.dll 모듈 안에 존재하는 WinProc을 target하고 있음을 추측할 수 있는데, 중요한 것은 해당 Module의 Symbol을 맞춰서 추가적으로 해당 Window Message(상위에서는 WM_IME_NOTIFY )에 대한 handling에 문제가 있는 것은 아닌지, 문제 시점에 정상적으로 해당 Window가 Message를 처리하고 있는 것인지 등을 확인해 볼 필요가 있을 것이다.
|
카테고리
이글루링크
최근 등록된 덧글
그러세요
by 강세윤 at 12/15 오늘 많이 헤매다..알게 .. by youna at 12/14 글 잘 읽었습니다 . 전 .. by 위시 at 11/26 어렷다 by klhk at 11/09 dhjjgbem by kl at 11/09 17번부터 어떻게 접는지.. by tykim0131 at 10/28 ATL이나 MFC를 이용하.. by 김명신 at 09/24 복원되었군요.. 제 RSS.. by 강세윤 at 09/24 허걱, 하고 있는 것으로.. by 강세윤 at 09/15 RSS 주소 서비스는 안 .. by 정성태 at 09/15 이글루 파인더
| |||