I. 소개
예제들을 통해 WinDbg의 사용법을 익힌다. WinDbg의 특정 명령에 대해서 더 자세히 알고자 하면 WinDbg의 문서를 참조해야 한다. http://www.microsoft.com/whdc/ddk/debugging/에서 아래의 윈도우즈 디버거들을 다운 받을 수 있다.
KD - Kernel debugger. OS에 문제가 생기거나 디바이스 드라이버들을 개발하는 경우에 사용한다.
CDB - Command-line debugger. 콘솔용 디버거이다.
NTSD - NT debugger. CDB에 윈도우 스타일 UI가 있는 유저-모드 디버거이다.
WinDbg - KD와 NTSD를 랩핑한 것으로 커널-모드와 유저-모드 디버거로서의 기능을 할 수 있다.
Visual Studio, Visual Studio .NET - KD와 NTSD와 동일한 디버깅 엔진을 사용하며, WinDbg보다 더 풍부한 디버깅 목적의 UI를 제공한다.
디버거들의 비교
특징 | KD | NTSD | WinDbg | Visual Studio .NET |
커널-모드 디버깅 | Y | N | Y | N |
유저-모드 디버깅 | Y | Y | Y | |
원격 디버깅 | Y | Y | Y | Y |
동작중 프로세스에 연결 | Y | Y | Y | Y |
II. WinDbg
WinDbg는 NTSD와 KD를 더 나은 UI로 래핑한 디버거이다. 최소화 상태로 시작(-m), pid를 통한 프로세스에 연결(-p), 크래쉬 파일들을 자동 열기(-z)와 같은 명령행 옵션들을 제공한다. 세가지 유형의 명령들을 지원한다.
정규 명령 : 프로세스들을 디버깅한다. (e.g. : k)
닷(dot) 명령 : 디버거를 제어한다. (e.g. : .sympath)
확장 명령 : WinDbg에 추가할 수 있는 커스텀 명령들로 확장 DLL들에서 익스포트된 함수들로 구현된다. (e.g. : !handle)
PDB 파일들
PDB 파일들은 링커에 의해 생성된 프로그램 데이터베이스 파일들이다. 비공개(private) PDB 파일들은 비공개 및 공개 심볼들, 소스 라인들, 타입들, 지역 및 전역변수들에 대한 정보를 포함한다. 공개(public) PDB 파일들은 타입들, 지역 및 소스 라인 정보를 포함하지 않는다.
디버깅 시나리오
리모트 디버깅
디버깅 서버(debugging server)라 함은 디버그 하고자 하는 머신상에 동작중인 디버거이며, 디버깅 클라이언트(debugging client)라 함은 세션을 제어하는 디버거이다.
서버상에는 CDB, NTSD, 또는 WinDbg가 필요한다. WinDbg 클라이언트는 CDB, NTSD 및 WinDbg중 아무에라도 연결할 수 있다. 서버와 클라이언트는 통신프로토콜로 TCP와 명명된 파이프들중에서 선택할 수 있다.
디버거를 이용하는 경우
서버 시작
WinDbg -server npipe:pipe=파이프명 (다수의 클라이언트가 접속할 수 있다.)
또는 WinDbg내에서
.server npipe:pipe=파이프명 (단일 클라이언트만 접속할 수 있다.)
클라이언트로 접속
WinDbg -remote npipe:server=서버, pipe=파이프명[,password=패스워드]
또는 WinDbg내에서 File->Connect to Remote Session
npipe:server=서버, pipe=파이프명 [,password=패스워드]
remote.exe를 이용하는 경우
remote.exe는 통신에 명명된 파이프들을 이용한다. 만약 KD, CDB 또는 NTSD와 같은 콘솔 기반 응용프로그램을 이용한다면, 리모트 디버깅을 하기위해 remote.exe를 이용할 수 있다.
서버 시작
remote.exe /s "cdb -p <pid>" test1
클라이언트로 연결
remote.exe /c <머신명> test1
'qq'로 서버를 종료하거나 또는 File->Exit를 사용하여 클라이언트를 종료할 수 있다. 리모트 디버깅을 하기 위해서는 사용자 그룹으로서 Debugger Users에 속해야 하며, 서버는 원격 연결을 허용해야만 한다.
Just-in-time 디버깅
WinDbg -I로 실행하면 기본 JIT 디버거로서 설정할 수 있다. 이 명령은 레지스트리 키 HKLM\Software\Microsoft\Windows NT\CurrentVersion\AeDebug를 WinDbg롤 설정한다. JIT 디버거로 설정되면, 응용프로그램인 디버깅중이 아닐 경우에 예외를 던지고 그 예외를 처리하지 않을 경우 WinDbg가 동작하게된다.
예외 디버깅
디버거는 각각의 예외에 2번 통지받는다. 응용프로그램이 예외를 처리하기 전에 first chance exception을 통지받고, 응용프로그램이 그 예외를 처리하지 않을 경우 second-chance excepton을 처리할 기회를 얻게된다. 디버거가 second-chance exception을 처리하지 않는다면, 응용프로그램은 종료한다.
.lastevent 또는 !analyze -v는 예외 기록과 예외가 발생했을 때의 함수의 스택 트레이스를 보여준다. .exr, .cxr 및 .ecxr 명령들을 예외 및 문맥 기록들(context records)을 화면에 표시하는데 사용할 수 있다. sxe, sxd, sxn 및 sxi 명령들을 이용하여 예외에 대해 first-chance 처리 옵션을 변경할 수 있다.
WinDbg 특징들
디버거 확장 DLL
디버거 확장은 디버거 내에서 커스텀 명령들을 실행할 수 있도록 디버거를 후킹(hook up)할 수 있도록 하는 DLL을 말한다. ! 명령들은 확장 DLL들로부터 실행되는 명령들이다. 확장 DLL들은 디버거의 프로세스 공간에 로드된다.
덤프 파일들
윈도우 OS가 깨지게 되면, 물리적 메모리 내용들과 모든 프로세스 정보가 덤프 파일에 기록된다. WinDbg를 JIT 디버거로 설정함으로써 비정상적으로 종료하는 모든 프로세스의 덤프를 만들 수 있다.
덤프 파일을 분석하기 위해 다음 단계들을 따른다.
Step 1: File->Open Crash Dump. 덤프 파일을 선택하여 연다.
Step 2: 실행 중인 응용프로그램의 명령들을 보여준다.
Step 3: 심볼 경로와 소스 경로를 적절히 설정한다.
WinDbg 설정
설치(Debugging Tools for Windows)
http://www.microsoft.com/whdc/devtools/debugging/default.mspx
설정
WinDbg에서 디버깅을 수행하기 위해서는 pdb 파일이 필요하다. Visual Studio에서 Debug Build로 빌드하면 Debug 폴더 안에 pdb 확장자 파일이 생긴다. 이 pdb파일을 WinDbg의 Symbol File Path에 복사해야 한다. Symbol File Path는 WinDbg의 File | Symbol File Path...[Ctrl+S] 메뉴에서 설정 가능하다.
실행
WinDbg의 File | Open Executable...[Ctrl+E] 메뉴를 클릭하여, 디버그할 실행 파일을 연다.
소스 레벨 디버깅
소스 레벨 디버깅을 하기 위해서는 소스 파일을 열어야 한다.
File | Open Source File...[Ctrl+O]