Create minidump file if FreeCAD crashes on Windows
This commit is contained in:
@@ -161,6 +161,10 @@ private:
|
||||
QDomDocument domDocument;
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
void InitMiniDumpWriter(const std::string&);
|
||||
#endif
|
||||
|
||||
#if defined (FC_OS_LINUX) || defined(FC_OS_BSD)
|
||||
QString myDecoderFunc(const QByteArray &localFileName)
|
||||
{
|
||||
@@ -224,6 +228,12 @@ int main( int argc, char ** argv )
|
||||
|
||||
// Inits the Application
|
||||
App::Application::init(argc,argv);
|
||||
#if defined(_MSC_VER)
|
||||
// create a dump file when the application crashes
|
||||
std::string dmpfile = App::Application::getUserAppDataDir();
|
||||
dmpfile += "crash.dmp";
|
||||
InitMiniDumpWriter(dmpfile);
|
||||
#endif
|
||||
Gui::Application::initApplication();
|
||||
Base::Interpreter().replaceStdOutput();
|
||||
}
|
||||
@@ -325,3 +335,99 @@ int main( int argc, char ** argv )
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
typedef BOOL (__stdcall *tMDWD)(
|
||||
IN HANDLE hProcess,
|
||||
IN DWORD ProcessId,
|
||||
IN HANDLE hFile,
|
||||
IN MINIDUMP_TYPE DumpType,
|
||||
IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
|
||||
IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
|
||||
IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
|
||||
);
|
||||
|
||||
static tMDWD s_pMDWD;
|
||||
static HMODULE s_hDbgHelpMod;
|
||||
static MINIDUMP_TYPE s_dumpTyp = MiniDumpNormal;
|
||||
static std::string s_szMiniDumpFileName; // initialize with whatever appropriate...
|
||||
|
||||
static LONG __stdcall MyCrashHandlerExceptionFilter(EXCEPTION_POINTERS* pEx)
|
||||
{
|
||||
#ifdef _M_IX86
|
||||
if (pEx->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW)
|
||||
{
|
||||
// be sure that we have enought space...
|
||||
static char MyStack[1024*128];
|
||||
// it assumes that DS and SS are the same!!! (this is the case for Win32)
|
||||
// change the stack only if the selectors are the same (this is the case for Win32)
|
||||
//__asm push offset MyStack[1024*128];
|
||||
//__asm pop esp;
|
||||
__asm mov eax,offset MyStack[1024*128];
|
||||
__asm mov esp,eax;
|
||||
}
|
||||
#endif
|
||||
bool bFailed = true;
|
||||
HANDLE hFile;
|
||||
hFile = CreateFile(s_szMiniDumpFileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
MINIDUMP_EXCEPTION_INFORMATION stMDEI;
|
||||
stMDEI.ThreadId = GetCurrentThreadId();
|
||||
stMDEI.ExceptionPointers = pEx;
|
||||
stMDEI.ClientPointers = TRUE;
|
||||
// try to create an miniDump:
|
||||
if (s_pMDWD(
|
||||
GetCurrentProcess(),
|
||||
GetCurrentProcessId(),
|
||||
hFile,
|
||||
s_dumpTyp,
|
||||
&stMDEI,
|
||||
NULL,
|
||||
NULL
|
||||
))
|
||||
{
|
||||
bFailed = false; // suceeded
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
if (bFailed)
|
||||
{
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// Optional display an error message
|
||||
// FatalAppExit(-1, ("Application failed!"));
|
||||
|
||||
|
||||
// or return one of the following:
|
||||
// - EXCEPTION_CONTINUE_SEARCH
|
||||
// - EXCEPTION_CONTINUE_EXECUTION
|
||||
// - EXCEPTION_EXECUTE_HANDLER
|
||||
return EXCEPTION_CONTINUE_SEARCH; // this will trigger the "normal" OS error-dialog
|
||||
}
|
||||
|
||||
void InitMiniDumpWriter(const std::string& filename)
|
||||
{
|
||||
if (s_hDbgHelpMod != NULL)
|
||||
return;
|
||||
s_szMiniDumpFileName = filename;
|
||||
|
||||
// Initialize the member, so we do not load the dll after the exception has occured
|
||||
// which might be not possible anymore...
|
||||
s_hDbgHelpMod = LoadLibrary(("dbghelp.dll"));
|
||||
if (s_hDbgHelpMod != NULL)
|
||||
s_pMDWD = (tMDWD) GetProcAddress(s_hDbgHelpMod, "MiniDumpWriteDump");
|
||||
|
||||
// Register Unhandled Exception-Filter:
|
||||
SetUnhandledExceptionFilter(MyCrashHandlerExceptionFilter);
|
||||
|
||||
// Additional call "PreventSetUnhandledExceptionFilter"...
|
||||
// See also: "SetUnhandledExceptionFilter" and VC8 (and later)
|
||||
// http://blog.kalmbachnet.de/?postid=75
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user