#include "wx/msw/crashrpt.h"
-#include <windows.h>
+#include "wx/msw/wrapwin.h"
#include <imagehlp.h>
#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
// ----------------------------------------------------------------------------
SYMBOL_TAG_BASECLASS
};
+#endif // wxUSE_DBGHELP
+
// ----------------------------------------------------------------------------
// classes
// ----------------------------------------------------------------------------
// 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);
void OutputGlobals(HANDLE hModuleCrash);
- // the handle of the report file
- HANDLE m_hFile;
-
// the current stack frame (may be NULL)
STACKFRAME *m_sfCurrent;
DECLARE_SYM_FUNCTION(SymSetContext);
DECLARE_SYM_FUNCTION(SymEnumSymbols);
DECLARE_SYM_FUNCTION(SymGetTypeInfo);
+#endif // wxUSE_DBGHELP
+
+ // the handle of the report file
+ HANDLE m_hFile;
};
// ----------------------------------------------------------------------------
// implementation
// ============================================================================
+#if wxUSE_DBGHELP
+
#define DEFINE_SYM_FUNCTION(func) func ## _t wxCrashReportImpl::func = 0
DEFINE_SYM_FUNCTION(SymSetOptions);
#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
(
va_end(argptr);
}
+#if wxUSE_DBGHELP
+
bool
wxCrashReportImpl::GetLogicalAddress(PVOID addr,
PTSTR szModule,
{
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;
}
{
wxString s;
+ // avoid infinite recursion
+ if ( level > 10 )
+ {
+ return s;
+ }
+
const HANDLE hProcess = GetCurrentProcess();
DWORD dwTag = 0;
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;
}
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; \
}
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)
{
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
// ----------------------------------------------------------------------------
);
wxStrncat(gs_reportFilename, fname,
- WXSIZEOF(gs_reportFilename) - strlen(gs_reportFilename) - 1);
+ WXSIZEOF(gs_reportFilename) - wxStrlen(gs_reportFilename) - 1);
}
return true;
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;