728x90
프로그램이 죽을 경우 덤프 파일 만들기
1. 솔루션 탐색기 - 프로젝트 우 클릭 - 추가 - 기존 항목 - MinidumpHelp.cs 추가
- dbghelp.dll 파일은 윈도우에 기본적으로 설치돼있지만 배포할 컴퓨터에 없는 경우 실행 파일과 함께 배포
2. 컴퓨터의 운영체제와 동일한 솔루션 플랫폼으로 반드시 변경
- 솔루션 플랫폼이 없을 경우 : 구성 관리자 - 활성 솔루션 플랫폼 - 새로 만들기
- 64bit 운영체제의 경우 솔루션 플랫폼을 x64로 변경하여 빌드
- Any CPU 불가
3. 소스
//Program.cs에 추가
namespace WindowsFormsApplication1
{
static class Program
{
//이벤트 클래스(UI 예외)
static void exceptionDump(object sender, System.Threading.ThreadExceptionEventArgs args)
{
//Exception e = args.Exception;
//Console.WriteLine("errMsg: " + e.Message);
//Console.WriteLine("errPos: " + e.TargetSite);
//덤프 파일 경로 설정(MinidumpHelp.cs 에서도 수정)
//MinidumpHelp.Minidump.install_self_mini_dump(Application.StartupPath);
MinidumpHelp.Minidump.install_self_mini_dump();
}
//이벤트 클래스(처리되지 않은 예외)
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
//Exception e = args.Exception;
//Console.WriteLine("errMsg: " + e.Message);
//Console.WriteLine("errPos: " + e.TargetSite);
//덤프 파일 경로 설정(MinidumpHelp.cs 에서도 수정)
//MinidumpHelp.Minidump.install_self_mini_dump(Application.StartupPath);
MinidumpHelp.Minidump.install_self_mini_dump();
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
//이벤트 추가
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(exceptionDump);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
4. 임의의 지점에 버그를 발생시켜 테스트
//강제 크래쉬(프로그램이 종료됨)
string[] p = new string[1];
p[2] = "a";
5. 크래쉬가 발생하면 실행 파일 위치에 .dmp 파일이 생성됨
- 파일명 : 년.월.일.시.분.초.dmp
6. 추후 배포 시 .exe 파일만 배포해도 되지만 덤프 파일을 받아 디버깅 시 반드시 같이 만든 .pdb 파일이 필요
- 배포할 때는 프로젝트를 비롯해 .exe와 .pdb 파일을 별도로 관리해야 함(.pdb 경로 동일)
- 배포 시 Debug와 Release 모드 상관 없음
덤프 파일 사용하기(.pdb 디버깅)
1. 크래쉬가 발생하여 생성된 덤프 파일을 실행
- windbg 같은 툴을 이용해도 되지만 여기에서는 visual studio를 이용
- windbg 설치 참고 - https://wendys.tistory.com/120
2. '관리 전용(으)로 디버그' 클릭

3. 크래쉬가 발생한 부분으로 화면이 전환
- 반드시 덤프 파일을 생성했던 .exe 파일과 같이 빌드 되었던 .pdb 파일이 필요
- 빌드 했던 프로젝트의 소스가 변경된 경우 크래쉬가 발생한 부분을 제대로 알 수 없음

+
.exe를 만들었을 당시와 프로젝트 폴더 이름이나 경로가 다른 경우
변경된 프로젝트 소스의 경로를 직접 설정
- 연결하는 창이 안 뜰 경우 호출 스택에서 노란 화살표가 가리키는 줄을 클릭하여 경로를 설정
프로그램이 죽었는데 덤프 파일이 안 생긴 경우
스택 오버 플로우로 죽은 경우 예외 처리 추가
typedef struct _MinidumpInfo
{
DWORD threadId; ///< crash가 발생한 threadId
EXCEPTION_POINTERS* pException; ///< 예외 포인터
} MinidumpInfo, *PMinidumpInfo;
int ExceptionHandler(EXCEPTION_POINTERS* pException)
{
if (pException->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW)
{
MinidumpInfo info;
info.threadId = ::GetCurrentThreadId();
info.pException = pException;
// 덤프 찍기용 쓰레드 하나 생성해 주고
HANDLE hThread = (HANDLE)_beginthreadex(0, THEAD_STACK_SIZE(대략 2메가), CreateMiniDump, &info, 0, NULL);
// 생성 쓰레드가 덤프 끝날 때까지 기다린다
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
else
{
/// 스택 오버플로우가 없는 일반적인 경우의 덤프 처리
}
return EXCEPTION_EXECUTE_HANDLER;
}
.pdb 파일 생성이 안 될 경우
1. 솔루션 탐색기 - 프로젝트 우 클릭 - 속성
2. 속성 페이지 - 구성 속성 - 링커 - 디버깅
3. 구성에서 Debug/Release 모드 둘 다 프로그램 데이터 베이스 파일 생성이 돼있는지 확인
- Debug/Release 모드에 상관없이 .pdb 파일이 있으면 덤프 파일 사용 가능

[출처]
728x90
'C#' 카테고리의 다른 글
GDI 개체 관리 (0) | 2023.11.04 |
---|---|
리플렉션 Reflection (1) (0) | 2023.11.04 |
병렬 프로그래밍 Parallel Programming (2) - 작업 병렬화 (0) | 2023.11.04 |
병렬 프로그래밍 Parallel Programming (1) - 데이터 병렬화 (0) | 2023.11.04 |
운영체제에서 제공하는 다양한 동기화 장치들에 대한 설명 (0) | 2023.11.04 |