Stack overflow: 사라진 Function 정보
*** 이글은 스크랩 자료이므로 추가 스크랩을 하지 말아 주시기 바랍니다. ***
원본 출처는 http://byung.egloos.com/3938350입니다.
-----------------------------------------------------------------------------------------------------------------
Stack overflow: 사라진 Function 정보
WinDBG로 Debugging할 때 가장 많이 사용하는 command 는 k command 입니다. 이유는 적어도 문제가 생긴 시점까지 진행된 Function을 확인해 보는 것이 중요할 것이고, 해당 Function들이 호출될 때 parameter들이 정상적으로 넘어 왔는지 한눈에 볼 수 있기 때문입니다.
0:000> kbL
ChildEBP RetAddr Args to Child
0012fd50 38373635 32313039 36353433 30393837 debuggingstuff!bar+0x7b
0012fe58 004115b5 0012ff40 00000000 00000000 0x38373635
0012ff48 00411bc6 00000001 008a2f50 008a1920 debuggingstuff!main+0x35
0012ff98 00411a0d 0012ffac 76a83833 7ffdf000 debuggingstuff!__tmainCRTStartup+0x1a6
0012ffa0 76a83833 7ffdf000 0012ffec 77d7a9bd debuggingstuff!mainCRTStartup+0xd
0012ffac 77d7a9bd 7ffdf000 0012fdbc 00000000 kernel32!BaseThreadInitThunk+0xe
0012ffec 00000000 00411127 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x23
적어도 상위의 callstack은 debuggingstuff.exe 에서 제공하는 main 함수 호출 후에 0x38373635라는 함수? 그리고, bar() 를 호출하여 문제가 발생한 것으로 보입니다. 한 눈에 보더라도 callstack이 깨진 것이 아닌가 의심하게 됩니다. 최상위 함수의 ebp 값을 통해 stack 상에 존재하는 데이터를 확인해 보면 아래와 같습니다. 보시는 바와 같이 알 수 없는 데이터로 인하여 stack이 overflow 된 것으로 보입니다. 이것을 Debugging 하는 방법은 stack이 깨지기 전의 callstack을 찾아서 그 위치에 break을 걸고 그 부분부터 문제가 발생한 시점까지 step by step debugging을 하여 문제를 찾아내는 것이 방법이며, 적어도 문제가 되는 함수를 review 하는 것도 방법일 수 있습니다.
0:000> dc 0012fd50
0012fd50 34333231 38373635 32313039 36353433 1234567890123456
0012fd60 30393837 34333231 38373635 32313039 7890123456789012
0012fd70 36353433 30393837 cccccc00 cccccccc 34567890........
0012fd80 cccccccc cccccccc cccccccc cccccccc ................
0012fd90 cccccccc cccccccc cccccccc cccccccc ................
0012fda0 cccccccc cccccccc cccccccc cccccccc ................
0012fdb0 cccccccc cccccccc cccccccc cccccccc ................
0012fdc0 cccccccc cccccccc cccccccc cccccccc ................
0012fdd0 cccccccc cccccccc cccccccc cccccccc ................
0012fde0 cccccccc cccccccc cccccccc cccccccc ................
0012fdf0 cccccccc cccccccc cccccccc cccccccc ................
0012fe00 cccccccc cccccccc cccccccc cccccccc ................
0012fe10 cccccccc cccccccc cccccccc cccccccc ................
0012fe20 cccccccc cccccccc cccccccc cccccccc ................
0012fe30 cccccccc cccccccc 01cccccc cccccccc ................
0012fe40 cccccccc 0000000a cccccccc cccccccc ................
0012fe50 00000000 cccccccc 0012ff48 004115b5 ........H.....A. ß-- 0012fe58 이 ebp값을 가지고 있을 지모른다.
0012fe60 0012ff40 00000000 00000000 7ffdf000 @...............
0012fe70 cccccccc cccccccc cccccccc cccccccc ................
0012fe80 cccccccc cccccccc cccccccc cccccccc ................
0012fe90 cccccccc cccccccc cccccccc cccccccc ................
0012fea0 cccccccc cccccccc cccccccc cccccccc ................
0012feb0 cccccccc cccccccc cccccccc cccccccc ................
0012fec0 cccccccc cccccccc cccccccc cccccccc ................
만일, 0012fe58이 가리키는 0012ff48이 ebp라면, 004115b5 는 return address 임에 틀림없을 것입니다. 그러므로, raw stack에서 찾아낸 정보가 stack이 깨지기 전의 온전한 function call임을 확인해야 합니다.
0:000> ln 004115b5
c:\users\byungck\documents\visual studio 2005\projects\debuggingstuff\debuggingstuff\debuggingstuff.cpp(45)+0x9
(00411580) debuggingstuff!main+0x35 | (0041163c) debuggingstuff!malloc
해당 함수는 main 함수임을 확인할 수 있습니다. 그리고 나면, 다음과 같이 온전한 마지막 callstack을 볼 수 있습니다.
0:000> kbL=0012fe58 0012ff48 004115b5 ß- kbL=<ebp pointer> <ebp> <return address>
ChildEBP RetAddr Args to Child
0012fe58 004115b5 0012ff40 00000000 00000000 debuggingstuff!main+0x35
0012ff48 00411bc6 00000001 008a2f50 008a1920 debuggingstuff!main+0x35
0012ff98 00411a0d 0012ffac 76a83833 7ffdf000 debuggingstuff!__tmainCRTStartup+0x1a6
0012ffa0 76a83833 7ffdf000 0012ffec 77d7a9bd debuggingstuff!mainCRTStartup+0xd
0012ffac 77d7a9bd 7ffdf000 0012fdbc 00000000 kernel32!BaseThreadInitThunk+0xe
0012ffec 00000000 00411127 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x23
해당 함수에 대한 address start는 00411580 입니다. 그리고 온전한 마지막 callstack은 offset이 0x35 이므로, 해당 instruction pointer는 004115b5 임이라는 것을 보여주죠.
0:000> ? 00411580 + 35
Evaluate expression: 4265397 = 004115b5
0:000> uf debuggingstuff!main
debuggingstuff!main [c:\users\byungck\documents\visual studio 2005\projects\debuggingstuff\debuggingstuff\debuggingstuff.cpp @ 41]:
41 00411580 55 push ebp
41 00411581 8bec mov ebp,esp
41 00411583 81ecd8000000 sub esp,0D8h
41 00411589 53 push ebx
41 0041158a 56 push esi
41 0041158b 57 push edi
41 0041158c 8dbd28ffffff lea edi,[ebp-0D8h]
41 00411592 b936000000 mov ecx,36h
41 00411597 b8cccccccc mov eax,0CCCCCCCCh
41 0041159c f3ab rep stos dword ptr es:[edi]
42 0041159e c745f800000000 mov dword ptr [ebp-8],0
43 004115a5 c745ec00000000 mov dword ptr [ebp-14h],0
45 004115ac 8d45f8 lea eax,[ebp-8]
45 004115af 50 push eax
45 004115b0 e864faffff call debuggingstuff!ILT+20(?fooYAJPAPADZ) (00411019)
45 004115b5 83c404 add esp,4
45 004115b8 8945ec mov dword ptr [ebp-14h],eax
47 004115bb 837df800 cmp dword ptr [ebp-8],0
47 004115bf 7416 je debuggingstuff!main+0x57 (004115d7)
그러므로, callstack에서 사라진 Function은 debuggingstuff!ILT+20(?fooYAJPAPADZ) foo function 입니다. (이것은 ebp frame 방식에서 보여주는 것이며, FPO형태에서는 적절하지 않을지 모릅니다.)
'프로그래밍???' 카테고리의 다른 글
C++ Builder에서의 삽질(MouseDown) (0) | 2008.06.20 |
---|---|
갑자기 느려진 디버깅... 원인을 찾다. (1) | 2008.04.25 |
stack overflow와의 한판 싸움 (0) | 2008.04.23 |
svchost.exe 관련 사항 (0) | 2008.04.16 |
big-endian and little-endian (0) | 2006.02.08 |