how to use windbg to debug .net application

C:\Windows\Microsoft.NET\Framework\*\sos.dll(2.0, 3.0, 4.0등 다양한 버전이 존재한다.)

해당 파일을 Windbg설치 디렉토리에 복사한 이후에 아래 명령을 이해해서 확장명령을 로드한다.

.load sos

[내용] .NET프레임워크 확장 명령 로드

정상적으로 로드가 되었는지 .chain 명령을 이용하여 정상적인 확장 명령어 로드 유무를 확인할 수 있다.

Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64

Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: “C:\Users\Home\Documents\Visual Studio 2008\Projects\StackOverflow\StackOverflow\bin\Debug\StackOverflow.exe”

WARNING: Whitespace at end of path element

Symbol search path is: SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols

;srv*c:\Symbols*http://msdl.microsoft.com/download/symbols

Executable search path is:

ModLoad: 0000000001060000 0000000001068000 StackOverflow.exe

ModLoad: 0000000077090000 0000000077239000 ntdll.dll

ModLoad: 000007fefb4e0000 000007fefb54f000 C:\Windows\SYSTEM32\MSCOREE.DLL

ModLoad: 0000000076b10000 0000000076c2f000 C:\Windows\system32\KERNEL32.dll

ModLoad: 000007fefd850000 000007fefd8bc000 C:\Windows\system32\KERNELBASE.dll

(11b0.938): Break instruction exception – code 80000003 (first chance)

ntdll!LdrpDoDebuggerBreak+0x30:

000000007713cb60 cc int 3

// 복사한 닷넷 라이브러리 파일을 로드한후 재로드를 시도한다.

0:000> .load sos

0:000> .reload

Reloading current modules

.....

// 라이브러리 연결상태 확인

0:000> .chain

Extension DLL search Path:

C:\windbg\WINXP;C:\windbg\winext;C:\windbg\winext\arcade;C:\windbg\pri;C:\windbg;C:\windbg\winext\arcade;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\WIDCOMM\Bluetooth Software\;C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;;C:\Program Files\Broadcom\Broadcom 802.11\Driver;C:\Program Files (x86)\Common Files\Roxio Shared\DLLShared\;C:\Program Files (x86)\Common Files\Roxio Shared\10.0\DLLShared\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\Microsoft Network Monitor 3\;C:\windbg;C:\Python27;C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin;C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE;C:\Program Files (x86)\IDA;C:\Program Files\Microsoft Windows Performance Toolkit\;C:\Program Files (x86)\SSH Communications Security\SSH Secure Shell;C:\Windows\Wbin;C:\Users\Home\AppData\Local\Bandizip\7z

Extension DLL chain:

// sos.dll이 잘 로드되어 있음을 알 수 있다.

sos: image 4.0.30319.488, API 1.0.0, built Sat Jul 09 15:55:38 2011

[path: C:\windbg\sos.dll]

dbghelp: image 6.12.0002.633, API 6.1.6, built Tue Feb 02 05:15:44 2010

[path: C:\windbg\dbghelp.dll]

ext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 05:15:46 2010

[path: C:\windbg\winext\ext.dll]

exts: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 05:15:38 2010

[path: C:\windbg\WINXP\exts.dll]

uext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 05:15:36 2010

[path: C:\windbg\winext\uext.dll]

ntsdexts: image 6.1.7650.0, API 1.0.0, built Tue Feb 02 05:15:18 2010

[path: C:\windbg\WINXP\ntsdexts.dll]

// 추가로 !help 명령을 이용하여 사용 가능한 확장 명령어를 확인하자.

0:000> !help

-------------------------------------------------------------------------------

SOS is a debugger extension DLL designed to aid in the debugging of managed

programs. Functions are listed by category, then roughly in order of

importance. Shortcut names for popular functions are listed in parenthesis.

Type "!help <functionname>" for detailed info on that function.

Object Inspection Examining code and stacks

----------------------------- -----------------------------

DumpObj (do) Threads

DumpArray (da) ThreadState

DumpStackObjects (dso) IP2MD

DumpHeap U

DumpVC DumpStack

GCRoot EEStack

ObjSize CLRStack

FinalizeQueue GCInfo

PrintException (pe) EHInfo

TraverseHeap BPMD

COMState

Examining CLR data structures Diagnostic Utilities

----------------------------- -----------------------------

DumpDomain VerifyHeap

EEHeap VerifyObj

Name2EE FindRoots

SyncBlk HeapStat

DumpMT GCWhere

DumpClass ListNearObj (lno)

DumpMD GCHandles

Token2EE GCHandleLeaks

EEVersion FinalizeQueue (fq)

DumpModule FindAppDomain

ThreadPool SaveModule

DumpAssembly ProcInfo

DumpSigElem StopOnException (soe)

DumpRuntimeTypes DumpLog

DumpSig VMMap

RCWCleanupList VMStat

DumpIL MinidumpMode

AnalyzeOOM (ao)

Examining the GC history Other

----------------------------- -----------------------------

HistInit FAQ

HistRoot

HistObj

HistObjFind

HistClear

[내용] sos 확장 모듈 확인

닷넷 프레임워크의 버전별 차이를 디버깅을 위해서는 버전별 디렉토리를 구분하여 로딩하여야 하는데 아래는 버전이 맞지 않아 정상적으로 확장 명령을 사용할 수 없는 오류에 대한 대처 방안이다.

0:000> !Threads

Failed to find runtime DLL (clr.dll), 0x80004005

Extension commands need clr.dll in order to have something to do.

0:000> .chain

Extension DLL search Path:

C:\windbg\WINXP;C:\windbg\winext;C:\windbg\winext\arcade;C:\windbg\pri;C:\windbg;C:\windbg\winext\arcade;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\WIDCOMM\Bluetooth Software\;C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;;C:\Program Files\Broadcom\Broadcom 802.11\Driver;C:\Program Files (x86)\Common Files\Roxio Shared\DLLShared\;C:\Program Files (x86)\Common Files\Roxio Shared\10.0\DLLShared\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\Microsoft Network Monitor 3\;C:\windbg;C:\Python27;C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin;C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE;C:\Program Files (x86)\IDA;C:\Program Files\Microsoft Windows Performance Toolkit\;C:\Program Files (x86)\SSH Communications Security\SSH Secure Shell;C:\Windows\Wbin;C:\Users\Home\AppData\Local\Bandizip\7z

Extension DLL chain:

sos: image 4.0.30319.488, API 1.0.0, built Sat Jul 09 15:55:38 2011 ß 4.0 버전 로드됨을 확인

[path: C:\windbg\sos.dll]

dbghelp: image 6.12.0002.633, API 6.1.6, built Tue Feb 02 05:15:44 2010

[path: C:\windbg\dbghelp.dll]

ext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 05:15:46 2010

[path: C:\windbg\winext\ext.dll]

exts: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 05:15:38 2010

[path: C:\windbg\WINXP\exts.dll]

uext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 05:15:36 2010

[path: C:\windbg\winext\uext.dll]

ntsdexts: image 6.1.7650.0, API 1.0.0, built Tue Feb 02 05:15:18 2010

[path: C:\windbg\WINXP\ntsdexts.dll]

// lm 명령을 통해 현재 mscorwks가 필요한지 확인한다. mscorwks가 메모리에 로드되어 있다면, 4.0 버전이 아닌 2.0 버전이 사용된다.

0:000> lm

start end module name

0000000001170000 0000000001178000 StackOverflow (deferred)

00000000741e0000 00000000742a9000 msvcr80 (deferred)

0000000076b10000 0000000076c2f000 kernel32 (deferred)

0000000076c30000 0000000076d2a000 user32 (deferred)

0000000077090000 0000000077239000 ntdll (pdb symbols) c:\websymbols\ntdll.pdb\15EB43E23B12409C84E3CC7635BAF5A32\ntdll.pdb

000007fef0d20000 000007fef1bfc000 mscorlib_ni (deferred)

000007fef1c00000 000007fef259c000 mscorwks (pdb symbols) c:\websymbols\mscorwks.pdb\A3BDE007E06845F7A0A4073CD16B1D7A1\mscorwks.pdb

000007fefb2c0000 000007fefb444000 mscorjit (deferred)

000007fefb450000 000007fefb4df000 mscoreei (deferred)

000007fefb4e0000 000007fefb54f000 mscoree (deferred)

000007fefd420000 000007fefd42f000 CRYPTBASE (deferred)

000007fefd4f0000 000007fefd4ff000 profapi (deferred)

000007fefd850000 000007fefd8bc000 KERNELBASE (deferred)

000007fefd9e0000 000007fefdbe3000 ole32 (deferred)

000007fefdbf0000 000007fefdcf9000 msctf (deferred)

000007fefdd00000 000007fefdd67000 gdi32 (deferred)

000007fefdfe0000 000007fefe0a9000 usp10 (deferred)

000007fefe0b0000 000007fefe14f000 msvcrt (deferred)

000007fefe150000 000007fefe15e000 lpk (deferred)

000007fefe160000 000007fefe17f000 sechost (deferred)

000007fefe300000 000007feff088000 shell32 (deferred)

000007feff090000 000007feff101000 shlwapi (deferred)

000007feff110000 000007feff1eb000 advapi32 (deferred)

000007feff240000 000007feff36d000 rpcrt4 (deferred)

000007feff370000 000007feff39e000 imm32 (deferred)

// 현재 로드된 4.0 버전을 언로드하고 2.0버전을 로드하자

0:000> !unload sos

Unloading sos extension DLL

0:000> !load C:\Windows\Microsoft.NET\Framework64\v2.0.50727\sos.dll

// 정상적으로 로드되었는지 확인

0:000> .chain

Extension DLL search Path:

C:\windbg\WINXP;C:\windbg\winext;C:\windbg\winext\arcade;C:\windbg\pri;C:\windbg;C:\windbg\winext\arcade;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\WIDCOMM\Bluetooth Software\;C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;;C:\Program Files\Broadcom\Broadcom 802.11\Driver;C:\Program Files (x86)\Common Files\Roxio Shared\DLLShared\;C:\Program Files (x86)\Common Files\Roxio Shared\10.0\DLLShared\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\Microsoft Network Monitor 3\;C:\windbg;C:\Python27;C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin;C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE;C:\Program Files (x86)\IDA;C:\Program Files\Microsoft Windows Performance Toolkit\;C:\Program Files (x86)\SSH Communications Security\SSH Secure Shell;C:\Windows\Wbin;C:\Users\Home\AppData\Local\Bandizip\7z

Extension DLL chain:

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\sos.dll: image 2.0.50727.5448, API 1.0.0, built Thu Jul 07 13:56:22 2011

[path: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\sos.dll]

dbghelp: image 6.12.0002.633, API 6.1.6, built Tue Feb 02 05:15:44 2010

[path: C:\windbg\dbghelp.dll]

ext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 05:15:46 2010

[path: C:\windbg\winext\ext.dll]

exts: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 05:15:38 2010

[path: C:\windbg\WINXP\exts.dll]

uext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 05:15:36 2010

[path: C:\windbg\winext\uext.dll]

ntsdexts: image 6.1.7650.0, API 1.0.0, built Tue Feb 02 05:15:18 2010

[path: C:\windbg\WINXP\ntsdexts.dll]

// 이후 확장명령이 정상적으로 실행됨을 확인할 수 있다.

0:003> !Threads

ThreadCount: 2

UnstartedThread: 0

BackgroundThread: 1

PendingThread: 0

DeadThread: 0

Hosted Runtime: no

PreEmptive Lock

ID OSID ThreadOBJ State GC GC Alloc Context Domain Count APT Exception

0 1 1e68 00000000000eb8d0 a020 Enabled 0000000002614368:0000000002615fd0 000000000008ff40 1 MTA

2 2 1f78 0000000000cc5130 b220 Enabled 0000000000000000:0000000000000000 000000000008ff40 0 MTA (Finalizer)

[내용] sos.dll 버전별로 관리하여야 한다

그럼 현재 일반 호출 스택 정보를 확인하자.

0:003> ~* e k

Child-SP RetAddr Call Site

00000000002367c8 0000000076b32ef8 ntdll!NtRequestWaitReplyPort+0xa

00000000002367d0 0000000076b33452 KERNEL32!ConsoleClientCallServer+0x54

0000000000236800 0000000076b335df KERNEL32!WriteConsoleInternal+0xb4

0000000000236910 000007fef1ebfd67 KERNEL32!WriteFileImplementation+0x45

0000000000236950 000007fef10b1e03 mscorwks!DoNDirectCall__PatchGetThreadCall+0x7b

0000000000236a00 000007fef10b222e mscorlib_ni+0x391e03

0000000000236b20 000007fef10b218a mscorlib_ni+0x39222e

0000000000236b80 000007fef10b27d7 mscorlib_ni+0x39218a

0000000000236be0 000007fef105cb76 mscorlib_ni+0x3927d7

0000000000236c40 000007fef1784b87 mscorlib_ni+0x33cb76

0000000000236c80 000007fef17859ab mscorlib_ni+0xa64b87

0000000000236cb0 000007ff00170198 mscorlib_ni+0xa659ab

0000000000236d00 000007ff001701b5 0x7ff00170198

0000000000236d40 000007ff001701b5 0x7ff001701b5

0000000000236d80 000007ff001701b5 0x7ff001701b5

0000000000236dc0 000007ff001701b5 0x7ff001701b5

0000000000236e00 000007ff001701b5 0x7ff001701b5

…중략

[내용] 일반적인 호출 스택 정보 확인

일반적인 호출 스택 정보로는 Mscorwks 초기화 작업이후 처리한 호출 스택으로 확인될 뿐 실제 내용을 확인하기가 상당히 여러운 상태이다 즉 상당히 고된 분석작업이 될 수 있다.

그럼 닷넷 프레임워크 확장 명령어를 이용하여 호출 스택을 확인해보도록 하자.

0:003> ~* e !clrstack

OS Thread Id: 0x1e68 (0)

*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v2.0.50727_64\mscorlib\18df8e7002edf6bcac8d375bc78f89f6\mscorlib.ni.dll

(!clrstack processes a max of 1000 stack frames)

Child-SP RetAddr Call Site

0000000000236a00 000007fef10b222e DomainNeutralILStubClass.IL_STUB(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte*, Int32, Int32 ByRef, IntPtr)

0000000000236b20 000007fef10b218a System.IO.__ConsoleStream.WriteFileNative(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte[], Int32, Int32, Int32, Int32 ByRef)

0000000000236b80 000007fef10b27d7 System.IO.__ConsoleStream.Write(Byte[], Int32, Int32)

0000000000236be0 000007fef105cb76 System.IO.StreamWriter.Flush(Boolean, Boolean)

0000000000236c40 000007fef1784b87 System.IO.TextWriter.Write(Int32)

0000000000236c80 000007fef17859ab System.IO.TextWriter.WriteLine(Int32)

0000000000236cb0 000007ff00170198 System.IO.TextWriter+SyncTextWriter.WriteLine(Int32)

0000000000236d00 000007ff001701b5 Program.Redo(Int32)

0000000000236d40 000007ff001701b5 Program.Redo(Int32)

0000000000236d80 000007ff001701b5 Program.Redo(Int32)

0000000000236dc0 000007ff001701b5 Program.Redo(Int32)

0000000000236e00 000007ff001701b5 Program.Redo(Int32)

0000000000236e40 000007ff001701b5 Program.Redo(Int32)

0000000000236e80 000007ff001701b5 Program.Redo(Int32)

0000000000236ec0 000007ff001701b5 Program.Redo(Int32)

0000000000236f00 000007ff001701b5 Program.Redo(Int32)

0000000000236f40 000007ff001701b5 Program.Redo(Int32)

0000000000236f80 000007ff001701b5 Program.Redo(Int32)

0000000000236fc0 000007ff001701b5 Program.Redo(Int32)

0000000000237000 000007ff001701b5 Program.Redo(Int32)

0000000000237040 000007ff001701b5 Program.Redo(Int32)

0000000000237080 000007ff001701b5 Program.Redo(Int32)

00000000002370c0 000007ff001701b5 Program.Redo(Int32)

0000000000237100 000007ff001701b5 Program.Redo(Int32)

0000000000237140 000007ff001701b5 Program.Redo(Int32)

0000000000237180 000007ff001701b5 Program.Redo(Int32)

00000000002371c0 000007ff001701b5 Program.Redo(Int32)

0000000000237200 000007ff001701b5 Program.Redo(Int32)

0000000000237240 000007ff001701b5 Program.Redo(Int32)

0000000000237280 000007ff001701b5 Program.Redo(Int32)

[내용] .NET 확장 명령을 이용한 호출 스택확인

위 내용처럼 우리가 사용한 프로그램 내 함수까지 정확히 구분하여 표시해 주므로써 원활한 분석을 가능하게 된다. 더욱이 닷넷 프레임워크는 많은 확장 명령어 옵션을 제공하여 편리하게 디버깅할 수 있는데 그 중에서도 아래 명령을 이용하여, 호출 스택의 로컬과 파라메터를 확인할 수 도 있다.

// -a와 -p 파라메터를 추가허면, 호출한 스택에서 사용한 파라메터와 값들에 대해 확인할 수 있다.
0:003> ~* e !clrstack -a -p

OS Thread Id: 0x1e68 (0)

(!clrstack processes a max of 1000 stack frames)

Child-SP RetAddr Call Site

0000000000236a00 000007fef10b222e DomainNeutralILStubClass.IL_STUB(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte*, Int32, Int32 ByRef, IntPtr)

PARAMETERS:

<no data>

<no data>

<no data>

<no data>

<no data>

0000000000236b20 000007fef10b218a System.IO.__ConsoleStream.WriteFileNative(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte[], Int32, Int32, Int32, Int32 ByRef)

PARAMETERS:

hFile = <no data>

bytes = <no data>

offset = <no data>

count = <no data>

mustBeZero = <no data>

errorCode = 0x0000000000236bb0

LOCALS:

0x0000000000236b50 = 0x0000000000000000

<no data>

<no data>

<no data>

0000000000236b80 000007fef10b27d7 System.IO.__ConsoleStream.Write(Byte[], Int32, Int32)

PARAMETERS:

this = <no data>

buffer = <no data>

offset = <no data>

count = <no data>

LOCALS:

0x0000000000236bb0 = 0x0000000000000000

<no data>

0000000000236be0 000007fef105cb76 System.IO.StreamWriter.Flush(Boolean, Boolean)

PARAMETERS:

this = <no data>

flushStream = <no data>

flushEncoder = <no data>

LOCALS:

<no data>

<CLR reg> = 0x00000000a9e60072

0000000000236c40 000007fef1784b87 System.IO.TextWriter.Write(Int32)

PARAMETERS:

this = <no data>

value = <no data>

0000000000236c80 000007fef17859ab System.IO.TextWriter.WriteLine(Int32)

PARAMETERS:

this = <no data>

value = <no data>

0000000000236cb0 000007ff00170198 System.IO.TextWriter+SyncTextWriter.WriteLine(Int32)

PARAMETERS:

this = 0x0000000002606b68

value = <no data>

0000000000236d00 000007ff001701b5 Program.Redo(Int32)

PARAMETERS:

value = 0x0000000000000606 ß 10진수로 1542

0000000000236d40 000007ff001701b5 Program.Redo(Int32)

PARAMETERS:

value = 0x0000000000000606

0000000000236d80 000007ff001701b5 Program.Redo(Int32)

PARAMETERS:

value = 0x0000000000000605

0000000000236dc0 000007ff001701b5 Program.Redo(Int32)

PARAMETERS:

value = 0x0000000000000604

0000000000236e00 000007ff001701b5 Program.Redo(Int32)

PARAMETERS:

value = 0x0000000000000603

…중략

[내용] 각 호출 스택에서 사용된 파라메터도 확인가능하다

우리가 프로그램을 정지하였을 때, 마지막 입력값인 1542이 저장되어 있음을 확인할 수 있다.

(이 값은 정지 포인트에 따라 독자마다 다를수 있다.)

[그림] 현재 최종값인 1542과 동일하다

이외에도 메모리 사용량을 확인할 수 있는 !address, 행(Hang)증상을 확인할 수 있는 !syncblk등 유용한 명령어 들이 다수 존재 하므로 닷넷 디버깅시 유용하게 사용하기 바란다.

-박스종료-

Facebook Comments

Leave A Reply

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.