1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// #include <stdafx.h>
#include "mdump.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <mbstring.h>
#include <wchar.h>
#include <TCHAR.H>
#include "../../ascstring.h"
#include "../../strtmesg.h"
// because the windows header are polluting the global namespace we can't include basestrm.h :-(
extern int getSearchPathNum();
extern ASCString getSearchPath ( int i );
LPCSTR MiniDumper::m_szAppName;
MiniDumper::MiniDumper( LPCSTR szAppName )
{
// if this assert fires then you have two instances of MiniDumper
// which is not allowed
assert( m_szAppName==NULL );
m_szAppName = szAppName ? strdup(szAppName) : "Application";
::SetUnhandledExceptionFilter( TopLevelFilter );
}
LONG MiniDumper::TopLevelFilter( struct _EXCEPTION_POINTERS *pExceptionInfo )
{
LONG retval = EXCEPTION_CONTINUE_SEARCH;
HWND hParent = NULL; // find a better value for your app
// firstly see if dbghelp.dll is around and has the function we need
// look next to the EXE first, as the one in System32 might be old
// (e.g. Windows 2000)
HMODULE hDll = NULL;
char szDbgHelpPath[_MAX_PATH];
if (GetModuleFileName( NULL, szDbgHelpPath, _MAX_PATH ))
{
char *pSlash = _tcsrchr( szDbgHelpPath, '\\' );
if (pSlash)
{
_tcscpy( pSlash+1, "DBGHELP.DLL" );
hDll = ::LoadLibrary( szDbgHelpPath );
}
}
if (hDll==NULL)
{
// load any version we can
hDll = ::LoadLibrary( "DBGHELP.DLL" );
}
LPCTSTR szResult = NULL;
if (hDll)
{
MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" );
if (pDump)
{
char szDumpPath[_MAX_PATH];
char szScratch [_MAX_PATH];
if ( getSearchPathNum() ) {
_tcscpy( szDumpPath, getSearchPath(0).c_str() );
} else {
// work out a good place for the dump file
if (!GetTempPath( _MAX_PATH, szDumpPath ))
_tcscpy( szDumpPath, "c:\\temp\\" );
}
_tcscat( szDumpPath, getFullVersionString() );
_tcscat( szDumpPath, m_szAppName );
_tcscat( szDumpPath, ".dmp" );
// ask the user if they want to save a dump file
// if (::MessageBox( NULL, "ASC has crashed. would you like to save a diagnostic file?", m_szAppName, MB_YESNO )==IDYES)
if ( true ) {
// create the file
HANDLE hFile = ::CreateFile( 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 = pDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL );
if (bOK)
{
sprintf( szScratch, "ASC has crashed :-(\nSaved dump file to '%s'\nPlease send it to bugs@asc-hq.org", szDumpPath );
szResult = szScratch;
retval = EXCEPTION_EXECUTE_HANDLER;
}
else
{
sprintf( szScratch, "Failed to save dump file to '%s' (error %d)", szDumpPath, GetLastError() );
szResult = szScratch;
}
::CloseHandle(hFile);
::MessageBox( NULL, szResult, m_szAppName, MB_OK | MB_ICONERROR );
return retval;
}
else
{
sprintf( szScratch, "Failed to create dump file '%s' (error %d)", szDumpPath, GetLastError() );
szResult = szScratch;
}
}
}
else
{
szResult = "DBGHELP.DLL too old";
::MessageBox( NULL, szDbgHelpPath, m_szAppName, MB_OK | MB_ICONERROR);
return retval;
}
}
else
{
szResult = "DBGHELP.DLL not found";
}
if (szResult)
::MessageBox( NULL, szResult, m_szAppName, MB_OK | MB_ICONERROR );
return retval;
}
|