-
Release 모드에서 오류 발생 시 자동 덤프 생성에서 분석까지...MFC 2015. 12. 24. 17:25
개발을 하다보면 Release 모드 상태에서 어느 순간 오류가 발생하는 경우가 생길 수 있다.
덤프 생성 및 분석을 위하여 해야할 일은 아래와 같다.
먼저 pdb 및 map 파일이 빌드 시 생성되도록 프로젝트 설정을 바꿔야 한다
1. C/C++ -> 일반 -> 디버그 정보 형식 에서 "프로그램 데이터베이스(/Zi)" 로 바꾼다.
2. C/C++ -> 일반 -> 명령줄 -> 추가옵션 에서 /Zo 를 추가한다
3. C/C++ -> 출력 파일 -> 어셈블러 출력 에서 "어셈블리, 기계어 코드, 소스"로 변경한다
4. 링커 -> 디버깅 -> 디버그 정보 생성 에서 "예" 선택
5. 링커 -> 디버깅 -> 맵 파일 생성 에서 "예" 선택
5. 생성된 dmp 파일을 pdb 파일 exe 파일과 같은 폴더에 넣고 분석한다
이렇게 하면 디버그 모드로 실행시에 변수 값과 오류 위치를 알 수 있다.
하지만. 릴리즈 모드로 실행 시 최적화 옵션이 걸려 있으면 변수 값이 나오지 않는 경우가 생길 수 있다.
이럴 경우 최적화 옵션을 잠시 꺼두고 프로그램을 실행하면 오류 위치와 메모리 값을 같이 보면서 디버깅 할 수 있다.
stdafx.h 에서 아래 추가
#include "dbghelp.h"
typedef BOOL(WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,
CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);extern LONG TopExceptionFilter(LPEXCEPTION_POINTERS pExp);
stdafx.cpp 에서 아래 추가
LONG TopExceptionFilter(LPEXCEPTION_POINTERS pExp)
{
LONG retval = EXCEPTION_CONTINUE_SEARCH;
HMODULE hDll = NULL;
hDll = ::LoadLibrary(_T("DBGHELP.DLL"));
TCHAR filename[32];
COleDateTime ct = COleDateTime::GetCurrentTime();
swprintf_s(filename, L"crash_%04d%02d%02d_%02d%02d%02d.dmp", ct.GetYear(), ct.GetMonth(), ct.GetDay(), ct.GetHour(), ct.GetMinute(), ct.GetSecond());if (hDll)
{
MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDll, "MiniDumpWriteDump");
if (pDump)
{
HANDLE hFile = ::CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
_MINIDUMP_EXCEPTION_INFORMATION ExInfo;ExInfo.ThreadId = ::GetCurrentThreadId();
ExInfo.ExceptionPointers = pExp;
ExInfo.ClientPointers = NULL;
BOOL bOK = pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpWithFullMemory, &ExInfo, NULL, NULL);
//BOOL bOK = pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL);if (bOK)
{
retval = EXCEPTION_EXECUTE_HANDLER;
}
::CloseHandle(hFile);
}
}
::FreeLibrary(hDll);
}return retval;
}프로그램 시작 시 아래 추가
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)TopExceptionFilter);