-#endif // wxUSE_DBGHELP
-
-bool wxCrashReportImpl::Generate(int flags)
-{
- if ( m_hFile == INVALID_HANDLE_VALUE )
- return false;
-
-#if wxUSE_DBGHELP
- if ( !wxGlobalSEInformation )
- return false;
-
- PEXCEPTION_RECORD pExceptionRecord = wxGlobalSEInformation->ExceptionRecord;
- PCONTEXT pCtx = wxGlobalSEInformation->ContextRecord;
-
- if ( !pExceptionRecord || !pCtx )
- return false;
-
- HANDLE hModuleCrash = OutputBasicContext(pExceptionRecord, pCtx);
-
- // for everything else we need dbghelp.dll
- wxDynamicLibrary dllDbgHelp(_T("dbghelp.dll"), wxDL_VERBATIM);
- if ( dllDbgHelp.IsLoaded() )
- {
- if ( ResolveSymFunctions(dllDbgHelp) )
- {
- SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME);
-
- // Initialize DbgHelp
- if ( SymInitialize(GetCurrentProcess(), NULL, TRUE /* invade */) )
- {
- OutputStack(pCtx, flags);
-
- if ( hModuleCrash && (flags & wxCRASH_REPORT_GLOBALS) )
- {
- OutputGlobals(hModuleCrash);
- }
-
- return true;
- }
- }
- else
- {
- Output(_T("Please update your dbghelp.dll version, "
- "at least version 5.1 is needed!\r\n"));
- }
- }
- else
- {
- Output(_T("Please install dbghelp.dll available free of charge ")
- _T("from Microsoft to get more detailed crash information!"));
- }
-
- Output(_T("\r\nLatest dbghelp.dll is available at "
- "http://www.microsoft.com/whdc/ddk/debugging/\r\n"));
-
-#else // !wxUSE_DBGHELP
- Output(_T("Support for crash report generation was not included ")
- _T("in this wxWindows version."));
-#endif // wxUSE_DBGHELP/!wxUSE_DBGHELP
-
- return true;
-}
-
-// ----------------------------------------------------------------------------
-// wxCrashReport
-// ----------------------------------------------------------------------------
-
-/* static */
-void wxCrashReport::SetFileName(const wxChar *filename)
-{
- wxStrncpy(gs_reportFilename, filename, WXSIZEOF(gs_reportFilename) - 1);
- gs_reportFilename[WXSIZEOF(gs_reportFilename) - 1] = _T('\0');
-}
-
-/* static */
-const wxChar *wxCrashReport::GetFileName()
-{
- return gs_reportFilename;
-}
-
-/* static */
-bool wxCrashReport::Generate(int flags)
-{
- wxCrashReportImpl impl(gs_reportFilename);
-
- return impl.Generate(flags);
-}
-
-// ----------------------------------------------------------------------------
-// wxApp::OnFatalException() support
-// ----------------------------------------------------------------------------
-
-bool wxHandleFatalExceptions(bool doit)
-{
- // assume this can only be called from the main thread
- gs_handleExceptions = doit;
-
- if ( doit )
- {
- // try to find a place where we can put out report file later
- if ( !::GetTempPath
- (
- WXSIZEOF(gs_reportFilename),
- gs_reportFilename
- ) )
- {
- wxLogLastError(_T("GetTempPath"));
-
- // when all else fails...
- wxStrcpy(gs_reportFilename, _T("c:\\"));
- }
-
- // use PID and date to make the report file name more unique
- wxString fname = wxString::Format
- (
- _T("%s_%s_%lu.rpt"),
- wxTheApp ? wxTheApp->GetAppName().c_str()
- : _T("wxwindows"),
- wxDateTime::Now().Format(_T("%Y%m%d")).c_str(),
- ::GetCurrentProcessId()
- );
-
- wxStrncat(gs_reportFilename, fname,
- WXSIZEOF(gs_reportFilename) - wxStrlen(gs_reportFilename) - 1);
- }
-
- return true;
-}
-
-extern unsigned long wxGlobalSEHandler(EXCEPTION_POINTERS *pExcPtrs)
-{
- if ( gs_handleExceptions && wxTheApp )
- {
- // store the pointer to exception info
- wxGlobalSEInformation = pExcPtrs;
-
- // give the user a chance to do something special about this
- __try
- {
- wxTheApp->OnFatalException();
- }
- __except ( EXCEPTION_EXECUTE_HANDLER )
- {
- // nothing to do here, just ignore the exception inside the
- // exception handler
- ;
- }
-
- wxGlobalSEInformation = NULL;
-
- // this will execute our handler and terminate the process
- return EXCEPTION_EXECUTE_HANDLER;
- }
-
- return EXCEPTION_CONTINUE_SEARCH;
-}
-
-#else // !wxUSE_ON_FATAL_EXCEPTION
-
-bool wxHandleFatalExceptions(bool WXUNUSED(doit))
-{
- wxFAIL_MSG(_T("set wxUSE_ON_FATAL_EXCEPTION to 1 to use this function"));
-
- return false;
-}
-
-#endif // wxUSE_ON_FATAL_EXCEPTION/!wxUSE_ON_FATAL_EXCEPTION