long WINAPI CCrashHandler::HandleExceptionGlobal ( _EXCEPTION_POINTERS* pException ) { // Create the exception information class CExceptionInformation_Impl* pExceptionInformation = new CExceptionInformation_Impl; pExceptionInformation->Set ( pException->ExceptionRecord->ExceptionCode, pException ); // Write the dump DumpMiniDump ( pException, pExceptionInformation ); RunErrorTool (); TerminateProcess ( GetCurrentProcess (), 1 ); return EXCEPTION_CONTINUE_SEARCH; }
void DumpMiniDump(HANDLE hFile, PEXCEPTION_POINTERS excpInfo) { if (excpInfo == NULL) { __try { RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL); } __except(DumpMiniDump(hFile, GetExceptionInformation()), EXCEPTION_CONTINUE_EXECUTION) { } }
void DumpMiniDump(PEXCEPTION_POINTERS excpInfo) { if (excpInfo == NULL) { // Generate exception to get proper context in dump __try { RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL); } __except(DumpMiniDump(GetExceptionInformation()),EXCEPTION_EXECUTE_HANDLER) { } }
//����Ҫ�ĺ���, ����Dump static void DumpMiniDump(HANDLE hFile, PEXCEPTION_POINTERS excpInfo) { if (excpInfo == NULL) //����û�д����쳣, �������ڳ����������õ�, ����һ���쳣 { // Generate exception to get proper context in dump __try { OutputDebugString(_T("raising exception\r\n")); RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL); } __except (DumpMiniDump(hFile, GetExceptionInformation()), EXCEPTION_CONTINUE_EXECUTION) { } }
int SaveMiniDump(PEXCEPTION_POINTERS pExceptPtrs) { TCHAR fileName[4096+4]; strcpy(fileName,"\\\\?\\"); fileName[sizeof(fileName)-5]=0; GetModuleFileName(0, fileName+4, sizeof(fileName)-4-4 ); if (testAssert(!fileName[sizeof(fileName)-5])) { lstrcat(fileName+4,".dmp"); HANDLE hFile = CreateFile( strlen(fileName+4)>MAX_PATH?fileName:fileName+4, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL); if (hFile != INVALID_HANDLE_VALUE) { DumpMiniDump(hFile, pExceptPtrs); CloseHandle(hFile); } } return EXCEPTION_CONTINUE_SEARCH; }
void main(void) { printf("Demonstrates the crash reporter.\n"); printf("This program will prompt you for a variety of actions to take on crash.\n"); printf("If so desired, it will generate a minidump which can be opened in visual studio\n"); printf("to debug the crash.\n\n"); RakNet::CrashReportControls controls; controls.actionToTake=0; printf("Send an email? (y/n)\n"); if (getch()=='y') { printf("Attach the mini-dump to the email? (y/n)\n"); if (getch()=='y') controls.actionToTake|=RakNet::AOC_EMAIL_WITH_ATTACHMENT; else controls.actionToTake|=RakNet::AOC_EMAIL_NO_ATTACHMENT; } printf("Write mini-dump to disk? (y/n)\n"); if (getch()=='y') controls.actionToTake|=RakNet::AOC_WRITE_TO_DISK; printf("Handle crashes in silent mode (no prompts)? (y/n)\n"); if (getch()=='y') controls.actionToTake|=RakNet::AOC_SILENT_MODE; if ((controls.actionToTake & RakNet::AOC_EMAIL_WITH_ATTACHMENT) || (controls.actionToTake & RakNet::AOC_EMAIL_NO_ATTACHMENT)) { if (controls.actionToTake & RakNet::AOC_SILENT_MODE) { printf("Enter SMTP Server: "); Gets(controls.SMTPServer,sizeof(controls.SMTPServer)); if (controls.SMTPServer[0]==0) return; printf("Enter SMTP account name: "); Gets(controls.SMTPAccountName,sizeof(controls.SMTPAccountName)); if (controls.SMTPAccountName[0]==0) return; printf("Enter sender email address: "); Gets(controls.emailSender,sizeof(controls.emailSender)); } printf("Enter email recipient email address: "); Gets(controls.emailRecipient,sizeof(controls.emailRecipient)); if (controls.emailRecipient[0]==0) return; printf("Enter subject prefix, if any: "); Gets(controls.emailSubjectPrefix,sizeof(controls.emailSubjectPrefix)); if ((controls.actionToTake & RakNet::AOC_SILENT_MODE)==0) { printf("Enter text to write in email body: "); Gets(controls.emailBody,sizeof(controls.emailBody)); } } if (controls.actionToTake & RakNet::AOC_WRITE_TO_DISK) { printf("Enter disk path to write to (ENTER for current directory): "); Gets(controls.pathToMinidump,sizeof(controls.pathToMinidump)); } printf("Enter application name: "); Gets(controls.appName,sizeof(controls.appName)); printf("Enter application version: "); Gets(controls.appVersion,sizeof(controls.appVersion)); // MiniDumpNormal will not give you SocketLayer::I correctly but is small (like 15K) // MiniDumpWithDataSegs is much bigger (391K) but does give you SocketLayer::I correctly. controls.minidumpType=MiniDumpWithDataSegs; // You must call Start before any crashes will be reported. RakNet::CrashReporter::Start(&controls); printf("Crash reporter started.\n"); // If you don't plan to debug the crash reporter itself, you can remove the __try within _DEBUG_CRASH_REPORTER #ifdef _DEBUG_CRASH_REPORTER __try #endif { RunGame(); } // If you don't plan to debug the crash reporter itself, you can remove the DumpMiniDump code within _DEBUG_CRASH_REPORTER #ifdef _DEBUG_CRASH_REPORTER __except(DumpMiniDump(GetExceptionInformation()),EXCEPTION_EXECUTE_HANDLER) { } #endif }
long WINAPI CCrashDumpWriter::HandleExceptionGlobal ( _EXCEPTION_POINTERS* pException ) { FreeMemoryForCrashDumpProcessing(); // Create the exception information class CExceptionInformation_Impl* pExceptionInformation = new CExceptionInformation_Impl; pExceptionInformation->Set ( pException->ExceptionRecord->ExceptionCode, pException ); WriteDebugEvent ( "CCrashDumpWriter::HandleExceptionGlobal" ); // Grab the mod manager CModManager* pModManager = CModManager::GetSingletonPtr (); if ( pModManager ) { // Got a client? if ( pModManager->GetCurrentMod () ) { // Protect us from "double-faults" try { // Let the client handle it. If it could, continue the execution if ( pModManager->GetCurrentMod ()->HandleException ( pExceptionInformation ) ) { // Delete the exception record and continue to search the exception stack delete pExceptionInformation; return EXCEPTION_CONTINUE_SEARCH; } // Save tick count now ms_uiTickCountBase = GetTickCount32 (); // The client wants us to terminate the process DumpCoreLog ( pExceptionInformation ); DumpMiniDump ( pException, pExceptionInformation ); RunErrorTool ( pExceptionInformation ); TerminateProcess ( GetCurrentProcess (), 1 ); } catch ( ... ) { // Double-fault, terminate the process DumpCoreLog ( pExceptionInformation ); DumpMiniDump ( pException, pExceptionInformation ); RunErrorTool ( pExceptionInformation ); TerminateProcess ( GetCurrentProcess (), 1 ); } } else { // Continue if we're in debug mode, if not terminate #ifdef MTA_DEBUG return EXCEPTION_CONTINUE_SEARCH; #endif } } // Terminate the process DumpCoreLog ( pExceptionInformation ); DumpMiniDump ( pException, pExceptionInformation ); RunErrorTool ( pExceptionInformation ); TerminateProcess ( GetCurrentProcess (), 1 ); return EXCEPTION_CONTINUE_SEARCH; }