ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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);

     

     

Designed by Tistory.