Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 3개 있습니다.)

Windbg - 비정상 종료된 닷넷 프로그램의 StackTrace에서 보이는 offset 값 의미

덤프 파일을 windbg로 열어서 예외 발생을 조사하는데,

0:000:x86> !threads
ThreadCount: 2
UnstartedThread: 0
BackgroundThread: 1
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
                                      PreEmptive   GC Alloc           Lock
       ID OSID ThreadOBJ    State     GC       Context       Domain   Count APT Exception
   0    1 1020 00000000004c5af0      a020 Enabled  00000000027b1fc4:00000000027b1fe8 00000000004bc878     0 MTA System.OutOfMemoryException (00000000027b1f1c)
   2    2 1d38 00000000004d27c0      b220 Enabled  0000000000000000:0000000000000000 00000000004bc878     0 MTA (Finalizer)

0:000:x86> !pe
Exception object: 00000000027b1f1c
Exception type: System.OutOfMemoryException
Message: <none>
InnerException: <none>
StackTrace (generated):
    SP       IP       Function
    0039F2F0 007A6D9C mscorlib!System.String.Concat(System.String, System.String, System.String)+0x7c
    0039F308 006FDD3E ConsoleApplication1!ConsoleApplication1.Program.Main(System.String[])+0x15e

StackTraceString: <none>
HResult: 8007000e

(HResult: 8007000e - Not enough storage is available to complete this operation.)

애석하게도 PDB 파일이 없는 관계로 소스 파일의 라인 번호가 아닌, "0x15e"라는 옵셋값만 출력됩니다. 다소 악조건의 상황이지만 이런 경우를 통해 windbg 사용법을 익혀 나가는 것 또한 그다지 나쁘지 않다는 긍정적인 판단하에 진행해 보았습니다.

우선, Main 메서드의 시작 위치를 알아야 합니다. 왜냐하면 실제로 예외가 발생한 System.String.Concat 메서드는 프레임워크 측의 코드이므로 그 위치를 알아낸다고 해서 그다지 크게 의미가 없습니다. 중요한 것은 "개발자가 작성한 코드"의 결함을 찾아내는 것이기 때문에 Concat 메서드를 부른 Main 메서드 내의 코드 위치를 알아내야 합니다.

이를 위해 name2ee 명령어로 다음과 같이 확인해 봐야겠지요. ^^

0:000:x86> !name2ee ConsoleApplication1!ConsoleApplication1.Program.Main
Module: 00000000001f2c70 (ConsoleApplication1.exe)
Token: 0x0000000006000001
MethodDesc: 00000000001f3010
Name: ConsoleApplication1.Program.Main(System.String[])
JITTED Code Address: 00000000006fdbe0

보는 바와 같이, 기계어로 번역된 Main 메서드의 코드 주소가 나옵니다. 이를 역어셈블 하기 위해 "!u" 명령어를 내려 볼까요?

0:000:x86> !u 00000000006fdbe0
Normal JIT generated code
ConsoleApplication1.Program.Main(System.String[])
Begin 00000000006fdbe0, size 1a0
>>> 0033:006fdbe0 <Effective machine and debuggee state conflict, disassembly not possible>
0033:006fdbe1 <Effective machine and debuggee state conflict, disassembly not possible>
...[이하 반복되는 오류 메시지]...

아쉽지만 사후(Post-mortem) 디버깅을 하는 상태에서는 Full Dump 파일임에도 불구하고 !u 명령어를 통해 정상적으로 역어셈블되지 않습니다. (PDB 파일이 없어서일까요? 나중에 확인해 봐야겠습니다. ^^)

그래도, 다행히 !u 명령어를 통해 메서드의 크기가 출력되었기 때문에 SOS의 "!u" 명령어가 아닌 Windbg 자체의 "u" 명령어를 이용하여 역어셈블 결과를 어렵지 않게 구할 수 있습니다.

0:000:x86> u 00000000006fdbe0 L1a0
006fdbe0 55              push    ebp
006fdbe1 8bec            mov     ebp,esp
006fdbe3 57              push    edi
006fdbe4 56              push    esi
006fdbe5 83ec70          sub     esp,70h
006fdbe8 33c0            xor     eax,eax
006fdbea 8945d8          mov     dword ptr [ebp-28h],eax
006fdbed 8945dc          mov     dword ptr [ebp-24h],eax
006fdbf0 8945e0          mov     dword ptr [ebp-20h],eax
006fdbf3 8945e4          mov     dword ptr [ebp-1Ch],eax
006fdbf6 894df4          mov     dword ptr [ebp-0Ch],ecx
006fdbf9 833d282e1f0000  cmp     dword ptr ds:[1F2E28h],0
006fdc00 7405            je      006fdc07
006fdc02 e86a39cf6b      call    mscorwks!CorLaunchApplication+0xe99e (6c3f1571)
006fdc07 33d2            xor     edx,edx
006fdc09 8955b0          mov     dword ptr [ebp-50h],edx
006fdc0c 33d2            xor     edx,edx
006fdc0e 8955f0          mov     dword ptr [ebp-10h],edx
006fdc11 33d2            xor     edx,edx
006fdc13 8955b8          mov     dword ptr [ebp-48h],edx
006fdc16 c745d400000000  mov     dword ptr [ebp-2Ch],0
006fdc1d c745e800000000  mov     dword ptr [ebp-18h],0
006fdc24 c745ec00000000  mov     dword ptr [ebp-14h],0
006fdc2b 33d2            xor     edx,edx
006fdc2d 8955b4          mov     dword ptr [ebp-4Ch],edx
006fdc30 90              nop
006fdc31 8b0db8217803    mov     ecx,dword ptr ds:[37821B8h]
006fdc37 ff15e40e7600    call    dword ptr ds:[760EE4h]
006fdc3d 90              nop
006fdc3e ff152c0e7600    call    dword ptr ds:[760E2Ch]
006fdc44 90              nop
006fdc45 b934117600      mov     ecx,761134h
006fdc4a e8cd43aeff      call    001e201c
006fdc4f 8945ac          mov     dword ptr [ebp-54h],eax
006fdc52 8b4dac          mov     ecx,dword ptr [ebp-54h]
006fdc55 ff15dcda7100    call    dword ptr ds:[71DADCh]
006fdc5b 8b45ac          mov     eax,dword ptr [ebp-54h]
006fdc5e 8945b8          mov     dword ptr [ebp-48h],eax
006fdc61 8b0580207803    mov     eax,dword ptr ds:[3782080h]
006fdc67 8945b4          mov     dword ptr [ebp-4Ch],eax
006fdc6a 33d2            xor     edx,edx
006fdc6c 8955f0          mov     dword ptr [ebp-10h],edx
006fdc6f 90              nop
006fdc70 e9e9000000      jmp     006fdd5e
006fdc75 90              nop
006fdc76 33c9            xor     ecx,ecx
006fdc78 ff15f8f67100    call    dword ptr ds:[71F6F8h]
006fdc7e 8945cc          mov     dword ptr [ebp-34h],eax
006fdc81 8955d0          mov     dword ptr [ebp-30h],edx
006fdc84 ff75d0          push    dword ptr [ebp-30h]
006fdc87 ff75cc          push    dword ptr [ebp-34h]
006fdc8a 6a00            push    0
006fdc8c 6800040000      push    400h
006fdc91 e8df82a96b      call    mscorwks+0x25f75 (6c195f75)
006fdc96 8945e8          mov     dword ptr [ebp-18h],eax
006fdc99 8955ec          mov     dword ptr [ebp-14h],edx
006fdc9c b9401e7100      mov     ecx,711E40h
006fdca1 e87643aeff      call    001e201c
006fdca6 8945a8          mov     dword ptr [ebp-58h],eax
006fdca9 8b05bc217803    mov     eax,dword ptr ds:[37821BCh]
006fdcaf 89458c          mov     dword ptr [ebp-74h],eax
006fdcb2 8b45a8          mov     eax,dword ptr [ebp-58h]
006fdcb5 8b4de8          mov     ecx,dword ptr [ebp-18h]
006fdcb8 8b55ec          mov     edx,dword ptr [ebp-14h]
006fdcbb 894804          mov     dword ptr [eax+4],ecx
006fdcbe 895008          mov     dword ptr [eax+8],edx
006fdcc1 8b45a8          mov     eax,dword ptr [ebp-58h]
006fdcc4 894588          mov     dword ptr [ebp-78h],eax
006fdcc7 ff35c0217803    push    dword ptr ds:[37821C0h]
006fdccd 8b4d8c          mov     ecx,dword ptr [ebp-74h]
006fdcd0 8b5588          mov     edx,dword ptr [ebp-78h]
006fdcd3 ff159c8e2900    call    dword ptr ds:[298E9Ch]
006fdcd9 8945a4          mov     dword ptr [ebp-5Ch],eax
006fdcdc 8b45a4          mov     eax,dword ptr [ebp-5Ch]
006fdcdf 8945b0          mov     dword ptr [ebp-50h],eax
006fdce2 8b45b8          mov     eax,dword ptr [ebp-48h]
006fdce5 8945a0          mov     dword ptr [ebp-60h],eax
006fdce8 8b45b0          mov     eax,dword ptr [ebp-50h]
006fdceb 89459c          mov     dword ptr [ebp-64h],eax
006fdcee 8d4dbc          lea     ecx,[ebp-44h]
006fdcf1 ff1580967100    call    dword ptr ds:[719680h]
006fdcf7 8d7dd8          lea     edi,[ebp-28h]
006fdcfa 8d75bc          lea     esi,[ebp-44h]
006fdcfd f30f7e06        movq    xmm0,mmword ptr [esi]
006fdd01 660fd607        movq    mmword ptr [edi],xmm0
006fdd05 f30f7e4608      movq    xmm0,mmword ptr [esi+8]
006fdd0a 660fd64708      movq    mmword ptr [edi+8],xmm0
006fdd0f 8d4dd8          lea     ecx,[ebp-28h]
006fdd12 ff15dc957100    call    dword ptr ds:[7195DCh]
006fdd18 894598          mov     dword ptr [ebp-68h],eax
006fdd1b 6800001000      push    100000h
006fdd20 ba43000000      mov     edx,43h
006fdd25 33c9            xor     ecx,ecx
006fdd27 e844820000      call    00705f70
006fdd2c 894594          mov     dword ptr [ebp-6Ch],eax
006fdd2f ff7594          push    dword ptr [ebp-6Ch]
006fdd32 8b5598          mov     edx,dword ptr [ebp-68h]
006fdd35 8b4d9c          mov     ecx,dword ptr [ebp-64h]
006fdd38 ff15cc8e2900    call    dword ptr ds:[298ECCh]
006fdd3e 894590          mov     dword ptr [ebp-70h],eax
006fdd41 8b5590          mov     edx,dword ptr [ebp-70h]
006fdd44 8b4da0          mov     ecx,dword ptr [ebp-60h]
006fdd47 3909            cmp     dword ptr [ecx],ecx
006fdd49 ff159cda7100    call    dword ptr ds:[71DA9Ch]
006fdd4f 90              nop
006fdd50 8b4db0          mov     ecx,dword ptr [ebp-50h]
006fdd53 ff15e40e7600    call    dword ptr ds:[760EE4h]
006fdd59 90              nop
006fdd5a 90              nop
006fdd5b ff45f0          inc     dword ptr [ebp-10h]
006fdd5e 817df0ffffff7f  cmp     dword ptr [ebp-10h],7FFFFFFFh
006fdd65 0f9cc0          setl    al
006fdd68 0fb6c0          movzx   eax,al
006fdd6b 8945d4          mov     dword ptr [ebp-2Ch],eax
006fdd6e 837dd400        cmp     dword ptr [ebp-2Ch],0
006fdd72 0f85fdfeffff    jne     006fdc75
006fdd78 90              nop
006fdd79 8d65f8          lea     esp,[ebp-8]
006fdd7c 5e              pop     esi
006fdd7d 5f              pop     edi
006fdd7e 5d              pop     ebp
006fdd7f c3              ret

이쯤에서 다시 처음으로 돌아가 "!pe" 결과로 출력된 옵셋값을 살펴보면,

StackTrace (generated):
    SP       IP       Function
    0039F308 006FDD3E ConsoleApplication1!ConsoleApplication1.Program.Main(System.String[])+0x15e

위의 의미는, Main 메서드의 최초 위치(006fdbe0)에서 0x15e 옵셋만큼 떨어진 기계어 코드를 가리키는 것임을 알 수 있습니다. 그 위치는 위의 결과에서 이미 IP(Instruction Pointer)로 출력된 "006FDD3E" 값과 동일합니다.

...[생략]...
006fdd2c 894594          mov     dword ptr [ebp-6Ch],eax
006fdd2f ff7594          push    dword ptr [ebp-6Ch]
006fdd32 8b5598          mov     edx,dword ptr [ebp-68h]
006fdd35 8b4d9c          mov     ecx,dword ptr [ebp-64h]
006fdd38 ff15cc8e2900    call    dword ptr ds:[298ECCh]
006fdd3e 894590          mov     dword ptr [ebp-70h],eax
006fdd41 8b5590          mov     edx,dword ptr [ebp-70h]
006fdd44 8b4da0          mov     ecx,dword ptr [ebp-60h]
006fdd47 3909            cmp     dword ptr [ecx],ecx
006fdd49 ff159cda7100    call    dword ptr ds:[71DA9Ch]
006fdd4f 90              nop
...[생략]...

이렇게 해서, 일단 예외가 발생한 기계어 코드의 위치는 찾았지만, 닷넷 개발자 입장에서 위의 정보는 여전히 직접적인 도움이 되지 않습니다. 문제는, 위의 기계어 코드와 일치하는 실제 C# 소스 코드 위치를 알 수 있는 방법이 있느냐 하는 것인데요. 만약, 자동으로 알 수 있는 방법이 있었다면 windbg가 이미 보여줄 수 있었을 텐데, 보관해 둔 PDB 파일이 없으므로 '자동'으로 찾을 수 있는 방법은 포기해야 합니다.

우선, 수작업으로 찾는 방법이 2가지 정도 있습니다. 하나는 말 그대로 기계어를 보면서, Main 함수의 소스 코드를 같이 보면서 찾아들어갈 수 있습니다. 다른 방법으로는, 위의 오류가 발생한 머신과 비슷한 환경을 꾸미고 소스 코드가 갖춰진 개발자 컴퓨터에서 Visual Studio에서 디버거를 붙여서 실행 시킨 후 "역어셈블" 화면을 보면서 유사하게 생성된 기계어 패턴을 따라가면서 소스 코드 위치를 파악하는 것입니다.

PDB 파일 보관을 제대로 하지 않았다면 이 정도 수고는 기꺼이 감수해야합니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 8/3/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13607정성태4/25/2024185닷넷: 2248.C# - 인터페이스 타입의 다중 포인터를 인자로 갖는 C/C++ 함수 연동
13606정성태4/24/2024200닷넷: 2247. C# - tensorflow 연동 (MNIST 예제)파일 다운로드1
13605정성태4/23/2024370닷넷: 2246. C# - Python.NET을 이용한 파이썬 소스코드 연동파일 다운로드1
13604정성태4/22/2024405오류 유형: 901. Visual Studio - Unable to set the next statement. Set next statement cannot be used in '[Exception]' call stack frames.
13603정성태4/21/2024704닷넷: 2245. C# - IronPython을 이용한 파이썬 소스코드 연동파일 다운로드1
13602정성태4/20/2024801닷넷: 2244. C# - PCM 오디오 데이터를 연속(Streaming) 재생 (Windows Multimedia)파일 다운로드1
13601정성태4/19/2024850닷넷: 2243. C# - PCM 사운드 재생(NAudio)파일 다운로드1
13600정성태4/18/2024878닷넷: 2242. C# - 관리 스레드와 비관리 스레드
13599정성태4/17/2024869닷넷: 2241. C# - WAV 파일의 PCM 사운드 재생(Windows Multimedia)파일 다운로드1
13598정성태4/16/2024889닷넷: 2240. C# - WAV 파일 포맷 + LIST 헤더파일 다운로드2
13597정성태4/15/2024880닷넷: 2239. C# - WAV 파일의 PCM 데이터 생성 및 출력파일 다운로드1
13596정성태4/14/20241067닷넷: 2238. C# - WAV 기본 파일 포맷파일 다운로드1
13595정성태4/13/20241051닷넷: 2237. C# - Audio 장치 열기 (Windows Multimedia, NAudio)파일 다운로드1
13594정성태4/12/20241069닷넷: 2236. C# - Audio 장치 열람 (Windows Multimedia, NAudio)파일 다운로드1
13593정성태4/8/20241084닷넷: 2235. MSBuild - AccelerateBuildsInVisualStudio 옵션
13592정성태4/2/20241219C/C++: 165. CLion으로 만든 Rust Win32 DLL을 C#과 연동
13591정성태4/2/20241198닷넷: 2234. C# - WPF 응용 프로그램에 Blazor App 통합파일 다운로드1
13590정성태3/31/20241079Linux: 70. Python - uwsgi 응용 프로그램이 k8s 환경에서 OOM 발생하는 문제
13589정성태3/29/20241154닷넷: 2233. C# - 프로세스 CPU 사용량을 나타내는 성능 카운터와 Win32 API파일 다운로드1
13588정성태3/28/20241268닷넷: 2232. C# - Unity + 닷넷 App(WinForms/WPF) 간의 Named Pipe 통신 [2]파일 다운로드1
13587정성태3/27/20241170오류 유형: 900. Windows Update 오류 - 8024402C, 80070643
13586정성태3/27/20241336Windows: 263. Windows - 복구 파티션(Recovery Partition) 용량을 늘리는 방법
13585정성태3/26/20241131Windows: 262. PerformanceCounter의 InstanceName에 pid를 추가한 "Process V2"
13584정성태3/26/20241249개발 환경 구성: 708. Unity3D - C# Windows Forms / WPF Application에 통합하는 방법파일 다운로드1
13583정성태3/25/20241471Windows: 261. CPU Utilization이 100% 넘는 경우를 성능 카운터로 확인하는 방법
[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...