2011. 1. 5. 22:22

Debugging With Minidump

예외 발생시 minidump 를 생성하는 Test Application 을 작성하였습니다. 1번째 참고한 사이트에서 제공하는 코드는 Multi-byte char set 으로 작성된거라 Unicode 에서는 빌드 에러 나더군요. 그리고 생성자에서 
strdup 함수를 사용하는데 여기에 메모리 릭이 있습니다. 예외가 나지 않은 경우 문제가 있더군요.
소소한 컴파일 에러와 버그를 수정한 버전을 아래 첨부하였습니다. VS 2008 에서 작성되었습니다.

소스 받은 후 빌드하고 실행해 보시면 되는데, 이상한 점은 Debug 모드에서 실행하면 정상적으로 minidump 가 수행되는데 Release 로 하면 minidump 가 수행되지 않았습니다. 이건 Visual Studio 가 설치된 것과 관련이 있는듯 한데 minidump 내용을 이해하는 것과는 무관하여 깊이 파고들지 않았습니다. 어쨋든 release 로 빌드된 exe 파일 역시 다른 환경에서는 정상적으로 dump 가 생성됩니다.

아래는 Windows 7 에서 빌드한 Release 버전의 실행 파일과 PDB 파일입니다.
PDB 파일은 나중에 minidump 를 open 할 때 필요합니다.


소스를 빌드한 동일한 PC 에서 생성된 minidump.dmp 파일을 열면 exe 나 pdb 파일을 동일한 위치에 복사하지 않아도 소스 정보를 볼 수 있었습니다. 하지만 다른 환경에서 dump 한 파일을 열려면 minidump.dmp 와 동일한 경로에 실행화일과 pdb 파일이 함께 있어야만 소스 정보를 제대로 보여주었습니다.

minidump 를 이용한 디버깅을 해보기 위해서 XP 에서 생성한 dump 파일을 사용하겠습니다. 아래 파일은 미리 
Windows XP 에서 dump 해놓은 파일입니다.


아래 그림처럼 minidump.dmp, MiniDump.exe, MiniDumpTest.pdb 파일을 동일한 폴더에 둡니다. 그냥 minidump.dmp 파일을 실행화일과 pdb 가 있는 곳에 복사하면 되겠죠.


minidump.dmp 파일을 더블 클릭합니다. (Visual Studio 가 설치되어 있다고 가정하겠습니다. WinDebug 로도 가능하다고 하니 WinDebug 를 이용한 방법은 구글에서 찾아보시기 바랍니다.)

Visual Studio 가 열린 상태에서 F5 를 누르거나 Start Debugging 메뉴를 선택하면 아래 그림과 같이 예외가 일어난 정보를 얻어올 수 있습니다.



놀랍기만 합니다. Windows XP 에서 재현된 문제를 Windows 7 에서 디버깅 하고 있다니요.

버그는 재현할 수 있다면 거의 해결한거나 마찬가지인데, 이런 minidump 를 이용한다면 보다 빨리 버그의 원인을 찾고 제거할 수 있을 것입니다.

내용 추가.

만약 불행히도 Minidump 를 생성하는 코드가 추가되어 있지 않은 경우에는 어떻게 minidump 를 생성하는지에 대해서도 알아보겠습니다. 

Dr.Watson 이용 (2000/2003/XP)

Dr. Watson 이라는 프로그램을 사용하면 crash 난 프로세스에 대해서 minidump 를 생성할 수 있습니다. 크래쉬가 발생하면 자동으로 Dr. Watson 이 덤프파일을 생성합니다. 이제 설정 방법과 실습을 해보겠습니다.

시작 > 실행 에서 drwtsn32 를 입력합니다. 


Dr.Watson 이 실행되면 아래처럼 설정 후 OK 를 선택합니다.

* Crash Dump Type: Mini
* Check "Dump Symbol Table", "Dump All Thread Contexts", & "Create Crash Dump File"
* Set "Number Of Instructions" and "Number Of Errors To Save" to 50
* Uncheck "Append to Existing Log"



확인을 누른 후 Crash 가 발생하면 Crash Dump 에 설정한 위치에 로그와 덤프파일이 자동으로 생성됩니다.

실습을 위해서는 Crash 가 일어나는 프로그램과 디버깅 정보를 가지고 있는 pdb 파일이 필요합니다.
CrashTest.exe 는 단순히 0 으로 나누기를 실행하는 코드가 있을뿐 이라 소스를 첨부하지는 않겠습니다.
디버깅 실습을 위해서는 소스가 필요할 것 같아 다시 생각을 바꿔 첨부합니다.

아래는 XP 에서 생성된 Dr. Watson 덤프 파일입니다.


이렇게 덤프파일 생성되면 디버깅하는 방법은 동일합니다. 아래 그럼처럼 user.dmp 파일을 exe 와 pdb 파일이 있는 위치로 복사를 합니다.


dmp 파일을 더블클릭하여 Visual Studio 를 띄웁니다. 그러고 나서 F5 를 누르면 아래와 같이 관련 정보를 얻을 수 있습니다.


Windows Vista, Server 2008, 그리고 Windows 7 에서 minidump 파일 생성하기

1. CrashTest.exe 실행 (Crash 재현)
2. 프로세스를 중지된 상태로 나둡니다.


3. 작업 관리자를 실행하고, 프로세스 탭에서 해당 프로세스를 찾습니다. 그런후 오른쪽 마우스를 클릭하면 아래 그림처럼 "덤프 파일 만들기"라는 메뉴가 있습니다. 


4. 덤프 파일 만들기를 선택합니다.



5. 로그 파일은 %USERPROFILE%\AppData\Local\Microsoft\Windows\WER\ReportArchive 위치에 생성됩니다.

Windows 7 에서 위 방법을 테스트 해보니 dump 파일은 생성이 되는데, 예외 지점을 가리키지 못하는 문제가 있습니다. 이는 좀더 살펴봐야 할 것 같습니다.

내용추가

Windows 7 에서 dump 파일을 자동으로 생성하는 방법을 드디어 찾았습니다.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps

레지스트리에 다음 사항을 추가해야 합니다. 만약 이 글에서 테스트한 CrashTest.exe 에 덤프 파일을 자동으로 생성하려고 한다면 아래 이미지 처럼 키와 값들을 추가해 주어야 합니다.


LocalDumps (존재하지 않으면 키를 만들어 주셔야 합니다) 하위에 CrashTest.exe 는 크래쉬가 난 경우 자동으로 dump 파일을 생성할 프로세스 명을 지정합니다.

DumpFolder 는 덤프 파일이 저장될 위치를 나타내는 문자열입니다. 
DumpCount 는 폴더에 생성할 최대 덤프 파일 개수를 가리킵니다. 만약 최대 값을 초과하면, 가장 오래된 파일은 새로운 파일로 교체 됩니다.
DumpType 은 덤프 타입을 가리킵니다. 0 은 Custom dump, 1 은 mini dump, 2 는 Full dump 입니다.
CustomDumpFlags 는 CumpType 이 0 인 경우 사용됩니다. 이 값은 MINIDUMP_TYPE 열거형 값의 비트 조합입니다. (자세한 내용은 6번 사이트를 참고하세요)

이렇게 레지스트리를 수정한 후 (재부팅 필요없습니다) CrashTest.exe 를 실행합니다. CrashTest.exe 의 작동이 중지되면 "프로그램 닫기"를 선택해서 그냥 닫아 버립니다. 


그냥 닫은 후 DumpFolder 에 지정한 폴더로 이동하면 (여기서는 d:\temp) 아래 그림처럼 덤프파일이 자동으로 생성되어 있습니다. 


생성된 파일 역시 첨부하겠습니다.

이 파일은 CrashTest.exe 와 pdb 파일이 있는 위치로 이동후 위에서 소개한 방법대로 디버깅을 하면 원하는 정보를 얻게 됩니다.


아후~,, 생각보다 글이 길어 졌네요. (파고들면..내용이 점점 늘어나는군요 ㅡㅡ;)
이 내용을 마지막으로 minidump 에 대한 내용은 일단락 하겠습니다.