WinDbg 시작(사용자 모드)
- 아티클
- 2023. 04. 14.
이 문서의 내용
WinDbg는 Windows용 디버깅 도구에 포함된 커널 모드 및 사용자 모드 디버거입니다. 다음 실습 연습은 WinDbg를 사용자 모드 디버거로 사용하기 시작하는 데 도움이 될 수 있습니다.
Windows용 디버깅 도구를 가져오는 방법에 대한 자세한 내용은 WinDbg Windows 디버거 다운로드 및 설치를 참조하세요.
디버깅 도구를 설치한 후 64비트(x64) 및 32비트(x86) 버전의 도구에 대한 설치 디렉터리를 찾습니다. 예:
- C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
- C:\Program Files (x86)\Windows Kits\10\Debuggers\x86
메모장을 열고 WinDbg 연결
- 설치 디렉터리로 이동하여 WinDbg.exe엽니다.
- 파일 메뉴에서 실행 파일 열기를 선택합니다. 실행 파일 열기 대화 상자에서 notepad.exe 포함된 폴더로 이동합니다. (notepad.exe 파일은 일반적으로 C:\Windows\System32에 있습니다. 파일 이름에 notepad.exe를 입력합니다. 열기를 선택합니다.
- WinDbg 창 아래쪽에 있는 명령줄에서 다음 명령을 입력합니다.출력은 다음 예제와 유사합니다.
- dbgcmd
- .sympath srv*
-
기호 검색 경로는 WinDbg에 기호(PDB) 파일을 찾을 위치를 알려줍니다. 디버거는 함수 이름 및 변수 이름과 같은 코드 모듈에 대한 정보를 가져오기 위해 기호 파일이 필요합니다..새로고침Symbol search path is: srv* Expanded Symbol search path is: cache*;SRV
- 명령은 .reload WinDbg에 기호 파일을 찾고 로드하기 위해 초기 검색을 수행하도록 지시합니다.
- 그런 다음, 다음 명령을 입력합니다.
- notepad.exe 모듈의 기호를 보려면 다음 명령을 입력합니다.
참고
출력이 표시되지 않으면 를 다시 입력 .reload 합니다.
- dbgcmd
- x notepad!wWin*
- x 메모장!*
-
00007ff6`6e76b0a0 notepad!wWinMain (wWinMain) 00007ff6`6e783db0 notepad!wWinMainCRTStartup (wWinMainCRTStartup)
- 에 notepad!wWinMain중단점을 배치하려면 다음 명령을 입력합니다.중단점이 설정되었는지 확인하려면 다음 명령을 입력합니다.출력은 다음 예제와 유사합니다.
- dbgcmd
- Bl
- bu notepad!wWinMain
-
0 e Disable Clear 00007ff6`6e76b0a0 0001 (0001) 0:**** notepad!wWinMain
- 메모장 프로세스를 시작하려면 다음 명령을 입력합니다.메모장 은 함수에 WinMain 올 때까지 실행된 다음 디버거에 침입합니다.
- dbgcmd
- g
Breakpoint 0 hit
notepad!wWinMain:
00007ff6`6e76b0a0 488bc4 mov rax,rsp
메모장 프로세스에 현재 로드된 코드 모듈 목록을 보려면 다음 명령을 입력합니다.
출력은 다음 예제와 유사합니다.
dbgcmd
0:000> lm
start end module name
00007ff6`6e760000 00007ff6`6e798000 notepad (pdb symbols) C:\ProgramData\Dbg\sym\notepad.pdb\BC04D9A431EDE299D4625AD6201C8A4A1\notepad.pdb
00007ff8`066a0000 00007ff8`067ab000 gdi32full (deferred)
00007ff8`067b0000 00007ff8`068b0000 ucrtbase (deferred)
00007ff8`06a10000 00007ff8`06aad000 msvcp_win (deferred)
00007ff8`06ab0000 00007ff8`06ad2000 win32u (deferred)
00007ff8`06b40000 00007ff8`06e08000 KERNELBASE (deferred)
00007ff8`07220000 00007ff8`072dd000 KERNEL32 (deferred)
00007ff8`07420000 00007ff8`07775000 combase (deferred)
00007ff8`07820000 00007ff8`079c0000 USER32 (deferred)
00007ff8`079c0000 00007ff8`079f0000 IMM32 (deferred)
00007ff8`07c00000 00007ff8`07c2a000 GDI32 (deferred)
00007ff8`08480000 00007ff8`085ab000 RPCRT4 (deferred)
00007ff8`085b0000 00007ff8`0864e000 msvcrt (deferred)
00007ff8`08c40000 00007ff8`08cee000 shcore (deferred)
00007ff8`08db0000 00007ff8`08fa5000 ntdll (pdb symbols) C:\ProgramData\Dbg\sym\ntdll.pdb\53F12BFE149A2F50205C8D5D66290B481\ntdll.pdb
00007fff`f8580000 00007fff`f881a000 COMCTL32 (deferred)
스택 추적을 보려면 다음 명령을 입력합니다.
출력은 다음 예제와 유사합니다.
dbgcmd
-
0:000> k 00 000000c8`2647f708 00007ff6`6e783d36 notepad!wWinMain 01 000000c8`2647f710 00007ff8`07237034 notepad!__scrt_common_main_seh+0x106 02 000000c8`2647f750 00007ff8`08e02651 KERNEL32!BaseThreadInitThunk+0x14 03 000000c8`2647f780 00000000`00000000 ntdll!RtlUserThreadStart+0x21
- 메모장 실행을 다시 시작하려면 다음 명령을 입력합니다.
- g
- 메모장에 침입하려면 파일 메뉴에서 중단을 선택합니다.
- 에서 ZwWriteFile중단점을 설정하고 확인하려면 다음 명령을 입력합니다.Bl
- bu ntdll! ZwWriteFile
- 메모장 실행을 다시 시작하려면 g를 입력 합니다. 메모장 창에서 텍스트를 입력합니다. 파일 메뉴에서 저장을 선택합니다. 실행 중인 코드는 에 관해서 에서 중단됩니다 ZwCreateFile. k 명령을 입력하여 스택 추적을 확인합니다.명령줄 왼쪽의 WinDbg 창에 프로세서 및 스레드 번호가 표시됩니다. 이 예제에서 현재 프로세서 번호는 0이고 현재 스레드 번호는 11(0:011>)입니다. 프로세서 0에서 실행되는 스레드 11의 스택 추적이 창에 표시됩니다.
- 메모장 프로세스의 모든 스레드 목록을 보려면 이 명령(타일)을 입력합니다.출력은 다음 예제와 유사합니다.
- dbgcmd
- ~
-
이 예제에서는 14개의 스레드에 인덱스가 0~13개 있습니다.0:011> ~ 0 Id: 5500.34d8 Suspend: 1 Teb: 000000c8`262c4000 Unfrozen 1 Id: 5500.3960 Suspend: 1 Teb: 000000c8`262c6000 Unfrozen 2 Id: 5500.5d68 Suspend: 1 Teb: 000000c8`262c8000 Unfrozen 3 Id: 5500.4c90 Suspend: 1 Teb: 000000c8`262ca000 Unfrozen 4 Id: 5500.4ac4 Suspend: 1 Teb: 000000c8`262cc000 Unfrozen 5 Id: 5500.293c Suspend: 1 Teb: 000000c8`262ce000 Unfrozen 6 Id: 5500.53a0 Suspend: 1 Teb: 000000c8`262d0000 Unfrozen 7 Id: 5500.3ca4 Suspend: 1 Teb: 000000c8`262d4000 Unfrozen 8 Id: 5500.808 Suspend: 1 Teb: 000000c8`262da000 Unfrozen 10 Id: 5500.3940 Suspend: 1 Teb: 000000c8`262dc000 Unfrozen . 11 Id: 5500.28b0 Suspend: 1 Teb: 000000c8`262de000 Unfrozen 12 Id: 5500.12bc Suspend: 1 Teb: 000000c8`262e0000 Unfrozen 13 Id: 5500.4c34 Suspend: 1 Teb: 000000c8`262e2000 Unfrozen
- 스레드 0에 대한 스택 추적을 보려면 다음 명령을 입력합니다.k
dbgcmd
- 출력은 다음 예제와 유사합니다.
- ~0s
-
0:011> ~0s 0:011> ~0s win32u!NtUserGetProp+0x14: 00007ff8`06ab1204 c3 ret 0:000> k # Child-SP RetAddr Call Site 00 000000c8`2647bd08 00007ff8`07829fe1 win32u!NtUserGetProp+0x14 01 000000c8`2647bd10 00007fff`f86099be USER32!GetPropW+0xd1 02 000000c8`2647bd40 00007ff8`07d12f4d COMCTL32!DefSubclassProc+0x4e 03 000000c8`2647bd90 00007fff`f8609aba SHELL32!CAutoComplete::_EditWndProc+0xb1 04 000000c8`2647bde0 00007fff`f86098b7 COMCTL32!CallNextSubclassProc+0x9a 05 000000c8`2647be60 00007ff8`0782e858 COMCTL32!MasterSubclassProc+0xa7 06 000000c8`2647bf00 00007ff8`0782de1b USER32!UserCallWinProcCheckWow+0x2f8 07 000000c8`2647c090 00007ff8`0782d68a USER32!SendMessageWorker+0x70b 08 000000c8`2647c130 00007ff8`07afa4db USER32!SendMessageW+0xda
- 디버깅을 종료하고 메모장 프로세스에서 분리하려면 다음 명령을 입력합니다.
- Qd
사용자 고유의 애플리케이션을 열고 WinDbg 연결
예를 들어 이 작은 콘솔 애플리케이션을 작성하고 빌드한 것으로 가정합니다.
C++
...
void MyFunction(long p1, long p2, long p3)
{
long x = p1 + p2 + p3;
long y = 0;
y = x / p2;
}
void main ()
{
long a = 2;
long b = 0;
MyFunction(a, b, 5);
}
이 연습에서는 빌드된 애플리케이션(MyApp.exe)과 기호 파일(MyApp.pdb)이 C:\MyApp\x64\Debug에 있다고 가정합니다. 또한 애플리케이션 소스 코드가 C:\MyApp\MyApp에 있고 대상 컴퓨터가 컴파일된 MyApp.exe 가정합니다.
- WinDbg를 엽니다.
- 파일 메뉴에서 실행 파일 열기를 선택합니다. 실행 파일 열기 대화 상자에서 C:\MyApp\x64\Debug로 이동합니다. 파일 이름에 MyApp.exe를 입력합니다. 열기를 선택합니다.
- 다음 명령을 입력합니다..sympath+ C:\MyApp\x64\Debug
- 명령은 WinDbg에 애플리케이션에 대한 기호 및 소스 코드를 찾을 수 있는 위치를 알려줍니다. 이 경우 기호에 원본 파일에 대한 정규화된 경로가 있으므로 .srcpath 를 사용하여 소스 코드 위치를 설정할 필요가 없습니다.
- .symfix
- 다음 명령을 입력합니다.bu MyApp! 기본애플리케이션은 해당 함수와 관련하여 디버거에 침입합니다 main .
- WinDbg는 소스 코드와 명령 창을 표시합니다.
- g
- .새로고침
- 디버그 메뉴에서 한 단계씩 실행(또는 F11 선택)을 선택합니다. 으로 한 단계씩 들어갈 때까지 계속 단계별로 MyFunction진행합니다. 줄을 y = x / p2한 단계씩 실행하면 애플리케이션이 충돌하고 디버거로 나뉩니다.
dbgcmd
- 출력은 다음 예제와 유사합니다.
-
(1450.1424): Integer divide-by-zero - code c0000094 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. MyApp!MyFunction+0x44: 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] ss:00000063`2036f808=00000000
- 다음 명령을 입력합니다.WinDbg는 문제의 분석을 표시합니다(이 경우 0으로 나누기).
- dbgcmd
- !analyze -v
-
FAULTING_IP: MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7] 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] EXCEPTION_RECORD: ffffffffffffffff -- (.exr 0xffffffffffffffff) ExceptionAddress: 00007ff63be11064 (MyApp!MyFunction+0x0000000000000044) ExceptionCode: c0000094 (Integer divide-by-zero) ExceptionFlags: 00000000 NumberParameters: 0 ... STACK_TEXT: 00000063`2036f7e0 00007ff6`3be110b8 : ... : MyApp!MyFunction+0x44 00000063`2036f800 00007ff6`3be1141d : ... : MyApp!main+0x38 00000063`2036f840 00007ff6`3be1154e : ... : MyApp!__tmainCRTStartup+0x19d 00000063`2036f8b0 00007ffc`b1cf16ad : ... : MyApp!mainCRTStartup+0xe 00000063`2036f8e0 00007ffc`b1fc4629 : ... : KERNEL32!BaseThreadInitThunk+0xd 00000063`2036f910 00000000`00000000 : ... : ntdll!RtlUserThreadStart+0x1d STACK_COMMAND: dt ntdll!LdrpLastDllInitializer BaseDllName ;dt ntdll!LdrpFailureData ;.cxr 0x0 ;kb FOLLOWUP_IP: MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7] 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] FAULTING_SOURCE_LINE: c:\myapp\myapp\myapp.cpp FAULTING_SOURCE_FILE: c:\myapp\myapp\myapp.cpp FAULTING_SOURCE_LINE_NUMBER: 7 FAULTING_SOURCE_CODE: 3: void MyFunction(long p1, long p2, long p3) 4: { 5: long x = p1 + p2 + p3; 6: long y = 0; > 7: y = x / p2; 8: } 9: 10: void main () 11: { 12: long a = 2; ...
명령 요약
- Contents 메뉴의 Help 명령
- .sympath(기호 경로 설정)
- .reload(모듈 다시 로드)
- x(기호 검사)
- g(Go)
- Break 메뉴의 Debug 명령
- lm(로드된 모듈 나열)
- k(디스플레이 스택 백트레이스)
- bu(중단점 설정)
- bl(중단점 목록)
- ~ (스레드 상태)
- ~s(현재 스레드 설정)
- .sympath+(기호 경로 설정)가 기존 기호 경로에 추가됨
- .srcpath(원본 경로 설정)
- Step Into 메뉴의 Debug 명령(F11)
- !analyze -v
- qd(종료 및 분리)
추가 정보
'[Microsoft]' 카테고리의 다른 글
환경 디버깅 (0) | 2023.12.06 |
---|---|
WinDbg 시작(커널 모드) (0) | 2023.12.06 |
Windows 디버깅 시작 (0) | 2023.12.06 |
Windows 드라이버 단계별 랩 디버그(에코 커널 모드) (0) | 2023.12.06 |
Windows 및 Windows Server 릴리스에 대한 메모리 제한 (1) | 2023.12.06 |