SendMessage호출에 의한 UI Thread Hang 현상

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 handle0x6034c 이고, 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에 문제가 있는 것은 아닌지, 문제 시점에 정상적으로 해당 WindowMessage를 처리하고 있는 것인지 등을 확인해 볼 필요가 있을 것이다.

 

by 강세윤 | 2009/07/23 16:10 | Windows debugging | 트랙백 | 덧글(0)
트랙백 주소 : http://byung.egloos.com/tb/5054797
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글

< 이전페이지 다음페이지 >