LONG Mini_Dump::WriteMiniDump(_EXCEPTION_POINTERS *pExceptionInfo) { LONG retvel = EXCEPTION_CONTINUE_SEARCH; m_pExceptionInfo = pExceptionInfo; HMODULE hDll = NULL; TCHAR szDbgHelpPath[_MAX_PATH]; if(GetModuleFileName(NULL,m_szAppPath,_MAX_PATH)) { TCHAR *pSlash = _tcsrchr(m_szAppPath, '\\'); if(pSlash) { _tcscpy(m_szAppBaseName,pSlash +1); *(pSlash+1) = 0; } _tcscpy(szDbgHelpPath,m_szAppPath); _tcscat(szDbgHelpPath,_T("DBGHELP.DLL")); hDll = ::LoadLibrary(szDbgHelpPath); } if(hDll == NULL) { hDll = ::LoadLibrary(_T("DBGHELP.DLL")); } LPCTSTR szResult = NULL; if(hDll) { MINIDUMPWRITEDUMP pMiniDumpWriteDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDll,"MiniDumpWriteDump"); if(pMiniDumpWriteDump) { TCHAR szScratch[_MAX_PATH]; VSetDumpFileName(); HANDLE hFile = ::CreateFile(m_szDumpPath,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile != INVALID_HANDLE_VALUE) { _MINIDUMP_EXCEPTION_INFORMATION ExInfo; ExInfo.ThreadId = ::GetCurrentThreadId(); ExInfo.ExceptionPointers = pExceptionInfo; ExInfo.ClientPointers = NULL; BOOL bOK = pMiniDumpWriteDump(GetCurrentProcess(),GetCurrentProcessId(), hFile,MiniDumpNormal,&ExInfo,VGetUserStreamArray(),NULL); if(bOK) { szResult = NULL; retvel = EXCEPTION_EXECUTE_HANDLER; } else { // _stprintf((wchar_t*)szResult, _T("에러 파일 저장 오류")); szResult = szScratch; } ::CloseHandle(hFile); } else { // _stprintf((wchar_t*)szResult, _T("에러 파일 생성 오류")); szResult = szScratch; } } else { szResult = _T("DGBHELP.DLL too Old"); } } else { szResult = _T("DGBHELP.DLL not found"); } if(szResult) ::MessageBox(NULL,szResult,NULL,MB_OK); TerminateProcess(GetCurrentProcess(),0); return retvel; }
// // MiniDumper::WriteMiniDump - Chapter 21, page 814 // LONG MiniDumper::WriteMiniDump(_EXCEPTION_POINTERS *pExceptionInfo ) { time( &m_lTime ); LONG retval = EXCEPTION_CONTINUE_SEARCH; m_pExceptionInfo = pExceptionInfo; // You have to find the right dbghelp.dll. // Look next to the EXE first since the one in System32 might be old (Win2k) HMODULE hDll = NULL; TCHAR szDbgHelpPath[_MAX_PATH]; if (GetModuleFileName( NULL, m_szAppPath, _MAX_PATH )) { TCHAR *pSlash = _tcsrchr( m_szAppPath, '\\' ); if (pSlash) { #ifdef _VS2005_ _tcscpy_s( m_szAppBaseName, pSlash + 1); #else _tcscpy( m_szAppBaseName, pSlash + 1 ); #endif *(pSlash+1) = 0; } #ifdef _VS2005_ _tcscpy_s( szDbgHelpPath, m_szAppPath ); _tcscat_s( szDbgHelpPath, _T("DBGHELP.DLL") ); #else _tcscpy( szDbgHelpPath, m_szAppPath ); _tcscat( szDbgHelpPath, _T("DBGHELP.DLL") ); #endif hDll = ::LoadLibrary( szDbgHelpPath ); } if (hDll==NULL) { // If we haven't found it yet - try one more time. hDll = ::LoadLibrary( _T("DBGHELP.DLL") ); } LPCTSTR szResult = NULL; if (hDll) { MINIDUMPWRITEDUMP pMiniDumpWriteDump = (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" ); if (pMiniDumpWriteDump) { TCHAR szScratch [USER_DATA_BUFFER_SIZE]; VSetDumpFileName(); // ask the user if they want to save a dump file _tcssprintf(szScratch, _T("There was an unexpected error:\n\n%s\nWould you like to save a diagnostic file?\n\nFilename: %s"), VGetUserMessage(), m_szDumpPath); if (m_bHeadless || (::MessageBox( NULL, szScratch, NULL, MB_YESNO )==IDYES)) { // create the file HANDLE hFile = ::CreateFile( m_szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (hFile!=INVALID_HANDLE_VALUE) { _MINIDUMP_EXCEPTION_INFORMATION ExInfo; ExInfo.ThreadId = ::GetCurrentThreadId(); ExInfo.ExceptionPointers = pExceptionInfo; ExInfo.ClientPointers = NULL; // write the dump BOOL bOK = pMiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, VGetUserStreamArray(), NULL ); if (bOK) { szResult = NULL; retval = EXCEPTION_EXECUTE_HANDLER; } else { _tcssprintf( szScratch, _T("Failed to save dump file to '%s' (error %d)"), m_szDumpPath, GetLastError() ); szResult = szScratch; } ::CloseHandle(hFile); } else { _tcssprintf( szScratch, _T("Failed to create dump file '%s' (error %d)"), m_szDumpPath, GetLastError() ); szResult = szScratch; } } } else { szResult = _T("DBGHELP.DLL too old"); } } else { szResult = _T("DBGHELP.DLL not found"); } if (szResult && !m_bHeadless) ::MessageBox( NULL, szResult, NULL, MB_OK ); TerminateProcess(GetCurrentProcess(), 0); // MLM Note: ExitThread will work, and it allows the MiniDumper to kill a crashed thread // without affecting the rest of the application. The question of the day: // Is That A Good Idea??? Answer: ABSOLUTELY NOT!!!!!!! // //ExitThread(0); return retval; }