|
Program의 수행에서 CPU의 연산을 위해 Stack을 사용한다는 점에서 Stack의 Size가 제한되어 있다는 것은 개발자라면 항상 염두에 두고 있을 것이다. 그러므로, 무한 재귀 호출되는 Function이나 과도하게 Stack 상에다 Allocation한 후(일반적으로 Local variables나 parameters는 Stack에 저장된다.) Exception이나 비정상적인 operation으로 인하여 Stack이 unwind 되지 않는 다면, 예기치 않은 Stack overflow를 맞을 수 있다. 다음의 Stack overflow dump case를 예로 든다. 일단, 메모리덤프를 Open 하면, 대번 Stack Overflow임을 알 수 있다. (24f8.f64): Stack overflow - code c00000fd (first/second chance not available) eax=000900a0 ebx=00000000 ecx=08ac2bf0 edx=0e010026 esi=0e010024 edi=08aff134 eip=033f9577 esp=08afebe8 ebp=08afec1c iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206 *** WARNING: Unable to verify checksum for ttt.dll *** ERROR: Symbol file could not be found. Defaulted to export symbols for ttt.dll - ttt!DllUnregisterServer+0x33a4: 033f9577 8501 test dword ptr [ecx],eax ds:0023:08ac2bf0=00000000 Stack Size는 다음과 같이 Check 할 수 있다. 0:066> !teb TEB at 7fefd000 ExceptionList: 08afec10 StackBase: 08b00000 StackLimit: 08ac1000 SubSystemTib: 00000000 FiberData: 00001e00 ArbitraryUserPointer: 00000000 Self: 7fefd000 EnvironmentPointer: 00000000 ClientId: 000024f8 . 00000f64 RpcHandle: 00000000 Tls Storage: 7fefd02c PEB Address: 7ffd8000 LastErrorValue: 0 LastStatusValue: c0150008 Count Owned Locks: 0 HardErrorMode: 0 0:066> ? 08b00000 - 08ac1000 Evaluate expression: 258048 = 0003f000 실제, Max Allocation할 수 있는 Stack Size를 확인해 보면, 대략 256k임을 확인할 수 있다. 이는 아래와 같은 TEB Structure의 DeallocationStack 값을 확인하면 되며, 이는 http://msdn.microsoft.com/en-us/library/cc267849.aspx 문서를 참조하거나 debugging tools for windows help에서 참조할 수 있다. typedef struct _TEB { 0:066> dd 7fefd000+e0c L1 7fefde0c 08ac0000 0:066> ? 08b00000 - 08ac0000 Evaluate expression: 262144 = 00040000 <---- 256k Max allocation size 그러므로, 현재 사용하는 Stack은 3f000 으로 Max Stack Size, 40000 에 도달하고 있음을 확인할 수 있다. 원인을 찾기 위해선 무엇보다도 먼저 재귀 호출이 있는 지 확인이 필요한데, 이는 Callstack을 확인하는 작업이 필요할 듯 하다. 일단, 해당 case에서는 안타깝게도 해당 모듈에 대한 Symbol이 정확하지 않아서 확인이 불가능했으며, 정확한 symbol이 존재한다면 아래의 Callstack에서 확인된 Function을 Check해야 한다. 0:066> kbL ChildEBP RetAddr Args to Child WARNING: Stack unwind information not available. Following frames may be wrong. 08afec1c 033f4de9 0df4002c 08aff0fc 0000fde9 ttt!DllUnregisterServer+0x33a4 <-- Symbol이 맞지 않아서 이렇게 보이는 것임. 08aff118 033f40c8 0b056198 0b056228 00000000 ttt+0x4de9 08aff170 762e31eb 0b055f20 08aff124 08aff120 ttt+0x40c8 08aff198 7635184f 033f3e71 08aff3a0 00000005 rpcrt4!Invoke+0x2a 08aff5c4 7634fc79 09dae6f8 06afcbc8 018be228 rpcrt4!NdrStubCall2+0x27b 08aff614 760527f7 09dae6f8 018be228 06afcbc8 rpcrt4!CStdStubBuffer_Invoke+0xffffdd13 08aff638 76909759 09dae6f8 018be228 06afcbc8 oleaut32!CUnivStubWrapper::Invoke+0xc7 . . . 만일, Function의 무한 재귀호출에 의해서 Stack Overflow가 발생한 것이 아니라면, Stack에 allocation 패턴도 Check해야 한다. 0:066> dds esp 08afebe8 75f751ea kernel32!lstrlenW+0x56 08afebec 033f18c5 ttt+0x18c5 08afebf0 08aff134 08afebf4 0b0584a8 08afebf8 08aff148 08afebfc 01e62f00 08afec00 0b0584a8 08afec04 000cc09e 08afec08 08afec24 08afec0c 033f188b ttt+0x188b 08afec10 08aff10c 08afec14 0340c9f0 ttt!DllUnregisterServer+0x1681d 08afec18 00000000 08afec1c 08aff118 08afec20 033f4de9 ttt+0x4de9 08afec24 0df4002c 08afec28 08aff0fc 08afec2c 0000fde9 08afec30 0000007b 08afec34 0b055f20 08afec38 00000005 08afec3c 00000000 Callstack에서 문제가 발생한 시점이전의 최종 Return Address가 33f4de9 인데, 그 이후에 Stack address(상위 raw stack에서의 회색 블럭)는 local variables 또는 parameters 등으로 사용되므로, 이들 중 Allocation 패턴이 overflow를 의심하게 하는 것이 있는 지 Check가 필요하다. 0:066> dc 0b0584a8 0b0584a8 0340e448 0b0500c4 00000000 00000000 H.@............. 0b0584b8 ee7ff470 08002142 00000001 0000261c p...B!.......&.. 0b0584c8 0000261c 000a000d 006f0043 0074006e .&......C.o.n.t. 0b0584d8 006e0065 002d0074 00790054 00650070 e.n.t.-.T.y.p.e. 0b0584e8 0020003a 006d0069 00670061 002f0065 :. .i.m.a.g.e./. 0b0584f8 00690067 003b0066 006e0020 006d0061 g.i.f.;. .n.a.m. 0b058508 003d0065 00630022 0069006c 005f0070 e.=.".c.l.i.p._. 0b058518 006d0069 00670061 00300065 00330030 i.m.a.g.e.0.0.3. 0:066> du 0b0584c8+8 0b0584d0 "Content-Type: image/gif; name="c" 0b058510 "lip_image003.gif"..Content-ID: <" 0b058550 "20090223.44575.001@tagfree.com>." 0b058590 ".Content-Transfer-Encoding: base" 0b0585d0 "64..Content-Location: file:///C:" 0b058610 "/DOCUME~1/jkim/LOCALS~1/Temp/mso" 0b058650 "html1/01/clip_image003.gif....R0" 0b058690 "lGODlhKwHTAHcAMSH+GlNvZnR3YXJlOi" 0b0586d0 "BNaWNyb3NvZnQgT2ZmaWNlACH5BAEAAA" 0b058710 "AALBUACQAA..AcMAhgAAAAAAABoaTSYm" 0b058750 "czMzmWaAgIAzAICAAJaWlpm/v5/P/57O" 0b058790 "/53O/5zN/5vN/5rM/5nM/79N..AL/d/7" 0b0587d0 "7d/7zc/7vb/7ra/7na/73c/7jZ/7fZ/7" 0b058810 "bY/7XY/7TY/7PX/7LX/7DW/6/W/7TX/6" 0b058850 "/V/67V../63U/6vT/6rT/6nT/6jT/6zU" 0b058890 "/6vU/6fS/6bS/6bR/6XR/6TQ/6PQ/6LQ" 0b0588d0 "/6HP/6DP/8Tf/8Le/8He../8De/8Pf/8" 0b058910 "z//9/u/97t/93s/9zr/9vr/9rq/9nq/9" 0b058950 "jq/9rr/9bp/9Xo/9Tn/9fp/9Lm/9Hm/8" 0b058990 "/l../9Pn/87l/83k/9Dm/8zj/8vj/8ni" 0b0589d0 "/8ji/8fh/8bh/8Xg//9mAP//AP//zP7/" 0b058a10 "//7+//3+//z9//v9..//v8//r8//n8//" 0b058a50 "j7//f7//b6//X5//T4//P4//L4//H3//" . . .<중략> 그러므로, 만일, 상위에서 보여주는 몇몇의 data가 과도한 Allocation이나 Allocation 패턴에 의해서 문제 상황을 가져오지는 않는 지는 최종적으로 Source Code를 통해서 확인해봐야 하며, 그러기 위해서는 정확한 Symbol의 match가 중요함을 잊지 말아야 한다.
|
카테고리
이글루링크
최근 등록된 덧글
그러세요
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 이글루 파인더
| |||