support creating larger minidumps; support WX_CRASH_FLAGS env var
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23996 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -26,15 +26,21 @@ enum
|
|||||||
wxCRASH_REPORT_LOCATION = 0,
|
wxCRASH_REPORT_LOCATION = 0,
|
||||||
|
|
||||||
// if this flag is given, the call stack is dumped
|
// if this flag is given, the call stack is dumped
|
||||||
|
//
|
||||||
|
// this results in dump/crash report as small as possible, this is the
|
||||||
|
// default flag
|
||||||
wxCRASH_REPORT_STACK = 1,
|
wxCRASH_REPORT_STACK = 1,
|
||||||
|
|
||||||
// if this flag is given, the values of the local variables are dumped
|
// if this flag is given, the values of the local variables are dumped
|
||||||
|
//
|
||||||
|
// note that this will result in huge file containing the dump of the
|
||||||
|
// entire process memory space when using mini dumps!
|
||||||
wxCRASH_REPORT_LOCALS = 2,
|
wxCRASH_REPORT_LOCALS = 2,
|
||||||
|
|
||||||
// if this flag is given, the values of all global variables are dumped
|
// if this flag is given, the values of all global variables are dumped
|
||||||
//
|
//
|
||||||
// WARNING: this may take a very long time and generate megabytes of output
|
// this creates a much larger mini dump and also takes more time to
|
||||||
// in a big program, this is why it is off by default
|
// generate if our own crash reporting code is used
|
||||||
wxCRASH_REPORT_GLOBALS = 4
|
wxCRASH_REPORT_GLOBALS = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -54,8 +60,7 @@ struct WXDLLIMPEXP_BASE wxCrashReport
|
|||||||
// write the exception report to the file, return true if it could be done
|
// write the exception report to the file, return true if it could be done
|
||||||
// or false otherwise
|
// or false otherwise
|
||||||
static bool Generate(int flags = wxCRASH_REPORT_LOCATION |
|
static bool Generate(int flags = wxCRASH_REPORT_LOCATION |
|
||||||
wxCRASH_REPORT_STACK |
|
wxCRASH_REPORT_STACK);
|
||||||
wxCRASH_REPORT_LOCALS);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // wxUSE_ON_FATAL_EXCEPTION
|
#endif // wxUSE_ON_FATAL_EXCEPTION
|
||||||
|
@@ -77,7 +77,7 @@
|
|||||||
//
|
//
|
||||||
// in any case, the user may override by defining wxUSE_DBGHELP himself
|
// in any case, the user may override by defining wxUSE_DBGHELP himself
|
||||||
#ifndef wxUSE_DBGHELP
|
#ifndef wxUSE_DBGHELP
|
||||||
#ifdef DBHLPAPI
|
#ifdef DBHLPAPI
|
||||||
#define wxUSE_DBGHELP 1
|
#define wxUSE_DBGHELP 1
|
||||||
#else
|
#else
|
||||||
#define wxUSE_DBGHELP 0
|
#define wxUSE_DBGHELP 0
|
||||||
@@ -172,6 +172,29 @@ enum SymbolTag
|
|||||||
// classes
|
// classes
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// low level wxBusyCursor replacement: we use Win32 API directly here instead
|
||||||
|
// of going through wxWindows calls as this could be dangerous
|
||||||
|
class BusyCursor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BusyCursor()
|
||||||
|
{
|
||||||
|
HCURSOR hcursorBusy = ::LoadCursor(NULL, IDC_WAIT);
|
||||||
|
m_hcursorOld = ::SetCursor(hcursorBusy);
|
||||||
|
}
|
||||||
|
|
||||||
|
~BusyCursor()
|
||||||
|
{
|
||||||
|
if ( m_hcursorOld )
|
||||||
|
{
|
||||||
|
::SetCursor(m_hcursorOld);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
HCURSOR m_hcursorOld;
|
||||||
|
};
|
||||||
|
|
||||||
// the real crash report generator
|
// the real crash report generator
|
||||||
class wxCrashReportImpl
|
class wxCrashReportImpl
|
||||||
{
|
{
|
||||||
@@ -1066,14 +1089,7 @@ wxString wxCrashReportImpl::GetExceptionString(DWORD dwCode)
|
|||||||
|
|
||||||
#endif // wxUSE_DBGHELP
|
#endif // wxUSE_DBGHELP
|
||||||
|
|
||||||
// Remove warning
|
bool wxCrashReportImpl::Generate(int flags)
|
||||||
#if wxUSE_DBGHELP && !wxUSE_MINIDUMP
|
|
||||||
#define WXUNUSED_LOCAL(x) x
|
|
||||||
#else
|
|
||||||
#define WXUNUSED_LOCAL WXUNUSED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool wxCrashReportImpl::Generate(int WXUNUSED_LOCAL(flags))
|
|
||||||
{
|
{
|
||||||
if ( m_hFile == INVALID_HANDLE_VALUE )
|
if ( m_hFile == INVALID_HANDLE_VALUE )
|
||||||
return false;
|
return false;
|
||||||
@@ -1092,6 +1108,25 @@ bool wxCrashReportImpl::Generate(int WXUNUSED_LOCAL(flags))
|
|||||||
HANDLE hModuleCrash = OutputBasicContext(pExceptionRecord, pCtx);
|
HANDLE hModuleCrash = OutputBasicContext(pExceptionRecord, pCtx);
|
||||||
#endif // !wxUSE_MINIDUMP
|
#endif // !wxUSE_MINIDUMP
|
||||||
|
|
||||||
|
// show to the user that we're doing something...
|
||||||
|
BusyCursor busyCursor;
|
||||||
|
|
||||||
|
// user-specified crash report flags override those specified by the
|
||||||
|
// programmer
|
||||||
|
TCHAR envFlags[64];
|
||||||
|
DWORD dwLen = ::GetEnvironmentVariable
|
||||||
|
(
|
||||||
|
_T("WX_CRASH_FLAGS"),
|
||||||
|
envFlags,
|
||||||
|
WXSIZEOF(envFlags)
|
||||||
|
);
|
||||||
|
|
||||||
|
int flagsEnv;
|
||||||
|
if ( dwLen && dwLen < WXSIZEOF(envFlags) &&
|
||||||
|
wxSscanf(envFlags, _T("%d"), &flagsEnv) == 1 )
|
||||||
|
{
|
||||||
|
flags = flagsEnv;
|
||||||
|
}
|
||||||
|
|
||||||
// for everything else we need dbghelp.dll
|
// for everything else we need dbghelp.dll
|
||||||
wxDynamicLibrary dllDbgHelp(_T("dbghelp.dll"), wxDL_VERBATIM);
|
wxDynamicLibrary dllDbgHelp(_T("dbghelp.dll"), wxDL_VERBATIM);
|
||||||
@@ -1107,12 +1142,31 @@ bool wxCrashReportImpl::Generate(int WXUNUSED_LOCAL(flags))
|
|||||||
minidumpExcInfo.ClientPointers = FALSE; // in our own address space
|
minidumpExcInfo.ClientPointers = FALSE; // in our own address space
|
||||||
|
|
||||||
// do generate the dump
|
// do generate the dump
|
||||||
|
MINIDUMP_TYPE dumpFlags;
|
||||||
|
if ( flags & wxCRASH_REPORT_LOCALS )
|
||||||
|
{
|
||||||
|
// the only way to get local variables is to dump the entire
|
||||||
|
// process memory space -- but this makes for huge (dozens or
|
||||||
|
// even hundreds of Mb) files
|
||||||
|
dumpFlags = MiniDumpWithFullMemory;
|
||||||
|
}
|
||||||
|
else if ( flags & wxCRASH_REPORT_GLOBALS )
|
||||||
|
{
|
||||||
|
// MiniDumpWriteDump() has the option for dumping just the data
|
||||||
|
// segment which contains all globals -- exactly what we need
|
||||||
|
dumpFlags = MiniDumpWithDataSegs;
|
||||||
|
}
|
||||||
|
else // minimal dump
|
||||||
|
{
|
||||||
|
dumpFlags = MiniDumpNormal;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !MiniDumpWriteDump
|
if ( !MiniDumpWriteDump
|
||||||
(
|
(
|
||||||
::GetCurrentProcess(),
|
::GetCurrentProcess(),
|
||||||
::GetCurrentProcessId(),
|
::GetCurrentProcessId(),
|
||||||
m_hFile, // file to write to
|
m_hFile, // file to write to
|
||||||
MiniDumpNormal, // just the minimum
|
dumpFlags, // kind of dump to craete
|
||||||
&minidumpExcInfo,
|
&minidumpExcInfo,
|
||||||
NULL, // no extra user-defined data
|
NULL, // no extra user-defined data
|
||||||
NULL // no callbacks
|
NULL // no callbacks
|
||||||
|
Reference in New Issue
Block a user