디버깅 .NET 어플리케이션책에 포함된, BugSlayer 소스를 vs2005/8 로 재컴파일한것(멀티쓰레드 DLL) 사용법은 압축파일을 받아서, bugslayer 폴드에 압축을 푼다. (예, c:/myproj/bugslayer) BugslayerUtil/BugslayerUtil.sln 프로젝트 파일을 열어서 release 모드로 컴파일 샘플 테스트 프로그램: bin/release/CrashTest.exe 라이버러리에 필요한 헤더파일 라이버러리를 복사 (예, c:/myproj/include/bugslayer, c:/myproj/bin/relase) copy_bugslayer.bat echo copy bugslayer... xcopy bugslayer\include\*.h ..\include\bugslayer /D xcopy bugslayer\bin\debug\CrashReport.* ..\bin\debug /D xcopy bugslayer\bin\debug\dbghelp.dll ..\bin\debug /D xcopy bugslayer\bin\Release\CrashReport.* ..\bin\release /D xcopy bugslayer\bin\release\dbghelp.dll ..\bin\release /D pause 적용할 프로젝트에 위 복사한 헤더파일 경로 지정, 라이버러리 경로 지정 c++ 옵션 /I c:/myproj/include/bugslayer 링커 옵션 /LIBPATH:c:/myproj/bin/release 콜스택을 출력할 다이얼로그 생성 WinMain 함수에 크래시 핸들러 설치 http://blog.naver.com/harkon.do?Redirect=Log&logNo=120036574686 - convUni2Mbcs() 함수 참조 #define LOG printf #define USE_CRASHHANDLER 1 #define TEST_CRASH 0 //테스트요: 강제 널포인트 참조 실행 #if USE_CRASHHANDLER #include "BugslayerUtil.h" #endif HINSTANCE hInst; // 현재 인스턴스입니다. TCHAR szTitle[MAX_LOADSTRING] = {"MyTest"}; // 제목 표시줄 텍스트입니다. #if USE_CRASHHANDLER #pragma comment (lib, "CrashReport.lib") EXCEPTION_POINTERS *g_pExPtrs; // 정보 대화 상자의 메시지 처리기입니다. LRESULT CALLBACK OnCrash(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { LPCTSTR szStr = NULL; HWND hList = 0; switch (message) { case WM_INITDIALOG: ShowCursor(TRUE); LOG("************************************ Crash Occured! ************************************"); szStr = GetFaultReason ( g_pExPtrs ) ; SetWindowText(GetDlgItem(hDlg, IDC_FAULTREASON), szStr) ; LOG("FaultRegion: %s", convUni2Mbcs(szStr).c_str()); szStr = GetRegisterString ( g_pExPtrs ) ; SetWindowText(GetDlgItem(hDlg, IDC_REGISTERS), szStr) ; LOG("Register:\n%s", convUni2Mbcs(szStr).c_str()); hList = GetDlgItem(hDlg, IDC_CALLSTACK); szStr = GetFirstStackTraceString ( GSTSO_MODULE | GSTSO_SYMBOL | GSTSO_SRCLINE , g_pExPtrs ) ; while ( NULL != szStr ) { SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)szStr); LOG(convUni2Mbcs(szStr).c_str()); szStr = GetNextStackTraceString ( GSTSO_MODULE | GSTSO_SYMBOL | GSTSO_SRCLINE , g_pExPtrs ) ; } LOG("****************************************************************************************"); EnableWindow(GetDlgItem(hDlg, IDC_MINIDUMP), IsMiniDumpFunctionAvailable ()); return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return TRUE; } else if (LOWORD(wParam) == IDC_MINIDUMP) { TCHAR dumpFile[100], szTmp[100]; wsprintf(dumpFile, _T("%s.DMP"), szTitle); //APPTITLE _T(".DMP"); BSUMDRET eRet = CreateCurrentProcessCrashDumpW ( MiniDumpWithHandleData , dumpFile, GetCurrentThreadId ( ) , g_pExPtrs ) ; ASSERT( eDUMP_SUCCEEDED == eRet ) ; if ( eDUMP_SUCCEEDED != eRet ) { wsprintf(szTmp, _T ("MiniDump Save, Failed. Code : %d") , eRet ) ; } else { wsprintf(szTmp, _T ("MiniDump Save, Succeed. %s"), dumpFile ) ; } MessageBox(NULL, szTmp, _T("MiniDump"), MB_OK); } break; } return FALSE; } LONG __stdcall TheCrashHandlerFunction ( EXCEPTION_POINTERS * pExPtrs ) { g_pExPtrs = pExPtrs ; LONG lReturnVal = EXCEPTION_EXECUTE_HANDLER ; INT_PTR iRet = DialogBox(NULL, (LPCTSTR)IDD_CRASH_DIALOG, NULL, (DLGPROC)OnCrash); if ( IDOK == iRet ) { lReturnVal = EXCEPTION_EXECUTE_HANDLER ; } else { lReturnVal = EXCEPTION_CONTINUE_SEARCH ; } g_pExPtrs = NULL; return ( lReturnVal ) ; } void TestCrashAway() { char * p = NULL ; *p = 'p' ; } #endif // USE_CRASHHANDLER int WinMain(LPCTSTR szName, HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { #if USE_CRASHHANDLER BOOL bRet = SetCrashHandlerFilter ( &TheCrashHandlerFunction ) ; ASSERT ( TRUE == bRet ) ; #if TEST_CRASH TestCrashAway(); #endif #endif InitInstance(...) CreateWindow(...) while (GetMessage(...)) { ... } return 0; }기타 MiniDump 버튼을 누르면, *.DMP 파일이 생성되며, 더블 클릭하면, 비주얼 스튜디오 실행되면서, 클래쉬한 소스의 위치를 가르킨다. 컴파일할때 /Zi 옵션으로, *.pdb 디버깅 심볼파일 생성 필요. 프로세스가 응답없음 상태일때, userdump.exe 를 이용한 미니 덤프 생성하기 압축 파일에 포함된 dbghelp.dll 버전에 따라서, 콜스택을 출력할때, 심볼(함수이름)을 제대로 못읽는 경우가 발생할수 있다. 이 경우, ms 사이트에서 최신버전을 찾아서 설치해 볼것. Bugslayer 와 비슷한 라이버러리 - 구글 breakpad 적용예 |
반응형
'디버깅 & 스킬 > 디버깅 & VS Debugging' 카테고리의 다른 글
assert의 비법들 (0) | 2012.11.28 |
---|---|
디버그용 ASSERT,assert 매크로 함수 소개 (0) | 2012.11.28 |
미니덤프, 힙 사용 미니덤프(minidump) vs2010 (0) | 2012.11.28 |
OCA 미니덤프 파일 디버깅 (0) | 2012.11.28 |
메모리 참조 오류 경고창에 나오는 값으로 디버깅하는 방법!?!? (0) | 2012.11.28 |