X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/50bea100324dcbeebf400eb65869fd4eae476171..ac8d0c118b7403e2838e75124b442051299e6f6c:/src/msw/crashrpt.cpp diff --git a/src/msw/crashrpt.cpp b/src/msw/crashrpt.cpp index 3b5da991bb..9dd8850bb0 100644 --- a/src/msw/crashrpt.cpp +++ b/src/msw/crashrpt.cpp @@ -40,10 +40,30 @@ #include "wx/msw/crashrpt.h" -#include +#include "wx/msw/wrapwin.h" #include #include "wx/msw/private.h" +// we need to determine whether we have the declarations for the function in +// debughlp.dll version 5.81 (at least) and we check for DBHLPAPI to test this +// +// reasons: +// - VC6 version of imagehlp.h doesn't define it +// - VC7 one does +// - testing for compiler version doesn't work as you can install and use +// the new SDK headers with VC6 +// +// in any case, the user may override by defining wxUSE_DBGHELP himself +#ifndef wxUSE_DBGHELP + #ifdef DBHLPAPI + #define wxUSE_DBGHELP 1 + #else + #define wxUSE_DBGHELP 0 + #endif +#endif + +#if wxUSE_DBGHELP + // ---------------------------------------------------------------------------- // types of imagehlp.h functions // ---------------------------------------------------------------------------- @@ -111,6 +131,8 @@ enum SymbolTag SYMBOL_TAG_BASECLASS }; +#endif // wxUSE_DBGHELP + // ---------------------------------------------------------------------------- // classes // ---------------------------------------------------------------------------- @@ -138,6 +160,7 @@ private: // output end of line void OutputEndl() { Output(_T("\r\n")); } +#if wxUSE_DBGHELP // translate exception code to its symbolic name static wxString GetExceptionString(DWORD dwCode); @@ -203,9 +226,6 @@ private: void OutputGlobals(HANDLE hModuleCrash); - // the handle of the report file - HANDLE m_hFile; - // the current stack frame (may be NULL) STACKFRAME *m_sfCurrent; @@ -223,6 +243,10 @@ private: DECLARE_SYM_FUNCTION(SymSetContext); DECLARE_SYM_FUNCTION(SymEnumSymbols); DECLARE_SYM_FUNCTION(SymGetTypeInfo); +#endif // wxUSE_DBGHELP + + // the handle of the report file + HANDLE m_hFile; }; // ---------------------------------------------------------------------------- @@ -243,6 +267,8 @@ static wxChar gs_reportFilename[MAX_PATH]; // implementation // ============================================================================ +#if wxUSE_DBGHELP + #define DEFINE_SYM_FUNCTION(func) func ## _t wxCrashReportImpl::func = 0 DEFINE_SYM_FUNCTION(SymSetOptions); @@ -258,13 +284,17 @@ DEFINE_SYM_FUNCTION(SymGetTypeInfo); #undef DEFINE_SYM_FUNCTION +#endif // wxUSE_DBGHELP + // ---------------------------------------------------------------------------- // wxCrashReportImpl // ---------------------------------------------------------------------------- wxCrashReportImpl::wxCrashReportImpl(const wxChar *filename) { +#if wxUSE_DBGHELP m_sfCurrent = NULL; +#endif // wxUSE_DBGHELP m_hFile = ::CreateFile ( @@ -291,6 +321,8 @@ void wxCrashReportImpl::Output(const wxChar *format, ...) va_end(argptr); } +#if wxUSE_DBGHELP + bool wxCrashReportImpl::GetLogicalAddress(PVOID addr, PTSTR szModule, @@ -400,10 +432,10 @@ wxCrashReportImpl::FormatSimpleValue(BasicType bt, { static const size_t NUM_CHARS = 32; - const wxChar * const pc = *(PSTR *)pAddress; - if ( !::IsBadStringPtr(pc, NUM_CHARS) ) + const char * const pc = *(PSTR *)pAddress; + if ( !::IsBadStringPtrA(pc, NUM_CHARS) ) { - s << _T('"') << wxString(pc, NUM_CHARS) << _T('"'); + s << _T('"') << wxString(pc, wxConvLibc, NUM_CHARS) << _T('"'); handled = true; } @@ -462,6 +494,12 @@ wxCrashReportImpl::FormatField(DWORD64 modBase, { wxString s; + // avoid infinite recursion + if ( level > 10 ) + { + return s; + } + const HANDLE hProcess = GetCurrentProcess(); DWORD dwTag = 0; @@ -642,7 +680,9 @@ wxCrashReportImpl::FormatSymbol(PSYMBOL_INFO pSym, STACKFRAME *sf) pVariable = (DWORD_PTR)pSym->Address; } - s << pSym->Name << _T(" = ") << FormatAnyValue(pSym, (PVOID)pVariable); + s << wxString(pSym->Name, wxConvLibc) + << _T(" = ") + << FormatAnyValue(pSym, (PVOID)pVariable); return s; } @@ -884,10 +924,10 @@ void wxCrashReportImpl::OutputGlobals(HANDLE hModule) bool wxCrashReportImpl::ResolveSymFunctions(const wxDynamicLibrary& dllDbgHelp) { #define LOAD_SYM_FUNCTION(name) \ - name = (name ## _t) dllDbgHelp.GetSymbol(#name); \ + name = (name ## _t) dllDbgHelp.GetSymbol(_T(#name)); \ if ( !name ) \ { \ - Output(_T("\r\nFunction ") __XFILE__(#name) \ + Output(_T("\r\nFunction ") _T(#name) \ _T("() not found.\r\n")); \ return false; \ } @@ -908,61 +948,6 @@ bool wxCrashReportImpl::ResolveSymFunctions(const wxDynamicLibrary& dllDbgHelp) return true; } -bool wxCrashReportImpl::Generate(int flags) -{ - if ( m_hFile == INVALID_HANDLE_VALUE ) - return false; - - 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); - - // 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")); - - return true; -} - /* static */ wxString wxCrashReportImpl::GetExceptionString(DWORD dwCode) { @@ -1018,6 +1003,76 @@ wxString wxCrashReportImpl::GetExceptionString(DWORD dwCode) return s; } +#endif // wxUSE_DBGHELP + +// Remove warning +#if wxUSE_DBGHELP +#define _WXUNUSED(x) x +#else +#define _WXUNUSED WXUNUSED +#endif + +bool wxCrashReportImpl::Generate(int _WXUNUSED(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, ") + _T("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 ") + _T("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 // ---------------------------------------------------------------------------- @@ -1078,7 +1133,7 @@ bool wxHandleFatalExceptions(bool doit) ); wxStrncat(gs_reportFilename, fname, - WXSIZEOF(gs_reportFilename) - strlen(gs_reportFilename) - 1); + WXSIZEOF(gs_reportFilename) - wxStrlen(gs_reportFilename) - 1); } return true; @@ -1092,7 +1147,16 @@ extern unsigned long wxGlobalSEHandler(EXCEPTION_POINTERS *pExcPtrs) wxGlobalSEInformation = pExcPtrs; // give the user a chance to do something special about this - wxTheApp->OnFatalException(); + __try + { + wxTheApp->OnFatalException(); + } + __except ( EXCEPTION_EXECUTE_HANDLER ) + { + // nothing to do here, just ignore the exception inside the + // exception handler + ; + } wxGlobalSEInformation = NULL;