X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7beafee9423f4cfa2fb08c8c5ff579f884314c79..07aaf32633ecf18ec3edfbb41793a112914792d0:/src/msw/stackwalk.cpp diff --git a/src/msw/stackwalk.cpp b/src/msw/stackwalk.cpp index 3872361952..9ff630ac76 100644 --- a/src/msw/stackwalk.cpp +++ b/src/msw/stackwalk.cpp @@ -1,8 +1,8 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: msw/stackwalk.cpp +// Name: src/msw/stackwalk.cpp // Purpose: wxStackWalker implementation for Win32 // Author: Vadim Zeitlin -// Modified by: +// Modified by: Artur Bac 2010-10-01 AMD64 Port // Created: 2005-01-08 // RCS-ID: $Id$ // Copyright: (c) 2003-2005 Vadim Zeitlin @@ -25,6 +25,10 @@ #if wxUSE_STACKWALKER +#ifndef WX_PRECOMP + #include "wx/string.h" +#endif + #include "wx/stackwalk.h" #include "wx/msw/debughlp.h" @@ -52,7 +56,7 @@ void wxStackFrame::OnGetName() wxZeroMemory(symbolBuffer); PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer; - pSymbol->SizeOfStruct = sizeof(symbolBuffer); + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_NAME_LEN; DWORD64 symDisplacement = 0; @@ -64,7 +68,7 @@ void wxStackFrame::OnGetName() pSymbol ) ) { - wxDbgHelpDLL::LogError(_T("SymFromAddr")); + wxDbgHelpDLL::LogError(wxT("SymFromAddr")); return; } @@ -92,7 +96,7 @@ void wxStackFrame::OnGetLocation() { // it is normal that we don't have source info for some symbols, // notably all the ones from the system DLLs... - //wxDbgHelpDLL::LogError(_T("SymGetLineFromAddr")); + //wxDbgHelpDLL::LogError(wxT("SymGetLineFromAddr")); return; } @@ -124,15 +128,15 @@ wxStackFrame::GetParam(size_t n, void wxStackFrame::OnParam(PSYMBOL_INFO pSymInfo) { - m_paramTypes.Add(_T("")); + m_paramTypes.Add(wxEmptyString); m_paramNames.Add(wxString::FromAscii(pSymInfo->Name)); // if symbol information is corrupted and we crash, the exception is going // to be ignored when we're called from WalkFromException() because of the - // except handler there returning EXCEPTION_CONTINUE_EXECUTION, but we'd be - // left in an inconsistent state, so deal with it explicitely here (even if - // normally we should never crash, of course...) + // exception handler there returning EXCEPTION_CONTINUE_EXECUTION, but we'd + // be left in an inconsistent state, so deal with it explicitly here (even + // if normally we should never crash, of course...) #ifdef _CPPUNWIND try #else @@ -150,21 +154,21 @@ void wxStackFrame::OnParam(PSYMBOL_INFO pSymInfo) __except ( EXCEPTION_EXECUTE_HANDLER ) #endif { - m_paramValues.Add(_T("")); + m_paramValues.Add(wxEmptyString); } } BOOL CALLBACK EnumSymbolsProc(PSYMBOL_INFO pSymInfo, ULONG WXUNUSED(SymSize), PVOID data) { - wxStackFrame *frame = wx_static_cast(wxStackFrame *, data); + wxStackFrame *frame = static_cast(data); // we're only interested in parameters if ( pSymInfo->Flags & IMAGEHLP_SYMBOL_INFO_PARAMETER ) { frame->OnParam(pSymInfo); } - + // return true to continue enumeration, false would have stopped it return TRUE; } @@ -186,7 +190,7 @@ void wxStackFrame::OnGetParam() // address, this is not a real error if ( ::GetLastError() != ERROR_INVALID_ADDRESS ) { - wxDbgHelpDLL::LogError(_T("SymSetContext")); + wxDbgHelpDLL::LogError(wxT("SymSetContext")); } return; @@ -201,7 +205,7 @@ void wxStackFrame::OnGetParam() this // data to pass to it ) ) { - wxDbgHelpDLL::LogError(_T("SymEnumSymbols")); + wxDbgHelpDLL::LogError(wxT("SymEnumSymbols")); } } @@ -210,12 +214,16 @@ void wxStackFrame::OnGetParam() // wxStackWalker // ---------------------------------------------------------------------------- -void wxStackWalker::WalkFrom(const CONTEXT *pCtx, size_t skip) +void wxStackWalker::WalkFrom(const CONTEXT *pCtx, size_t skip, size_t maxDepth) { if ( !wxDbgHelpDLL::Init() ) { - wxLogError(_("Failed to get stack backtrace:\n%s"), + // don't log a user-visible error message here because the stack trace + // is only needed for debugging/diagnostics anyhow and we shouldn't + // confuse the user by complaining that we couldn't generate it + wxLogDebug(wxT("Failed to get stack backtrace: %s"), wxDbgHelpDLL::GetErrorMessage().c_str()); + return; } // according to MSDN, the first parameter should be just a unique value and @@ -232,7 +240,7 @@ void wxStackWalker::WalkFrom(const CONTEXT *pCtx, size_t skip) TRUE // load symbols for all loaded modules ) ) { - wxDbgHelpDLL::LogError(_T("SymInitialize")); + wxDbgHelpDLL::LogError(wxT("SymInitialize")); return; } @@ -245,7 +253,16 @@ void wxStackWalker::WalkFrom(const CONTEXT *pCtx, size_t skip) STACKFRAME sf; wxZeroMemory(sf); -#ifdef _M_IX86 +#if defined(_M_AMD64) + sf.AddrPC.Offset = ctx.Rip; + sf.AddrPC.Mode = AddrModeFlat; + sf.AddrStack.Offset = ctx.Rsp; + sf.AddrStack.Mode = AddrModeFlat; + sf.AddrFrame.Offset = ctx.Rbp; + sf.AddrFrame.Mode = AddrModeFlat; + + dwMachineType = IMAGE_FILE_MACHINE_AMD64; +#elif defined(_M_IX86) sf.AddrPC.Offset = ctx.Eip; sf.AddrPC.Mode = AddrModeFlat; sf.AddrStack.Offset = ctx.Esp; @@ -259,7 +276,7 @@ void wxStackWalker::WalkFrom(const CONTEXT *pCtx, size_t skip) #endif // _M_IX86 // iterate over all stack frames - for ( size_t nLevel = 0; ; nLevel++ ) + for ( size_t nLevel = 0; nLevel < maxDepth; nLevel++ ) { // get the next stack frame if ( !wxDbgHelpDLL::StackWalk @@ -276,7 +293,7 @@ void wxStackWalker::WalkFrom(const CONTEXT *pCtx, size_t skip) ) ) { if ( ::GetLastError() ) - wxDbgHelpDLL::LogError(_T("StackWalk")); + wxDbgHelpDLL::LogError(wxT("StackWalk")); break; } @@ -285,46 +302,46 @@ void wxStackWalker::WalkFrom(const CONTEXT *pCtx, size_t skip) if ( nLevel >= skip ) { wxStackFrame frame(nLevel - skip, - (void *)sf.AddrPC.Offset, + wxUIntToPtr(sf.AddrPC.Offset), sf.AddrFrame.Offset); OnStackFrame(frame); } } - // this results in crashes inside ntdll.dll when called from - // exception handler ... -#if 0 if ( !wxDbgHelpDLL::SymCleanup(hProcess) ) { - wxDbgHelpDLL::LogError(_T("SymCleanup")); + wxDbgHelpDLL::LogError(wxT("SymCleanup")); } -#endif } -void wxStackWalker::WalkFrom(const _EXCEPTION_POINTERS *ep, size_t skip) +void wxStackWalker::WalkFrom(const _EXCEPTION_POINTERS *ep, size_t skip, size_t maxDepth) { - WalkFrom(ep->ContextRecord, skip); + WalkFrom(ep->ContextRecord, skip, maxDepth); } -void wxStackWalker::WalkFromException() +#if wxUSE_ON_FATAL_EXCEPTION + +void wxStackWalker::WalkFromException(size_t maxDepth) { extern EXCEPTION_POINTERS *wxGlobalSEInformation; wxCHECK_RET( wxGlobalSEInformation, - _T("wxStackWalker::WalkFromException() can only be called from wxApp::OnFatalException()") ); + wxT("wxStackWalker::WalkFromException() can only be called from wxApp::OnFatalException()") ); // don't skip any frames, the first one is where we crashed - WalkFrom(wxGlobalSEInformation, 0); + WalkFrom(wxGlobalSEInformation, 0, maxDepth); } -void wxStackWalker::Walk(size_t skip) +#endif // wxUSE_ON_FATAL_EXCEPTION + +void wxStackWalker::Walk(size_t skip, size_t WXUNUSED(maxDepth)) { // to get a CONTEXT for the current location, simply force an exception and // get EXCEPTION_POINTERS from it // // note: - // 1. we additionally skip RaiseException() and WalkFromException() frames + // 1. we additionally skip RaiseException() and WalkFrom() frames // 2. explicit cast to EXCEPTION_POINTERS is needed with VC7.1 even if it // shouldn't have been according to the docs __try @@ -334,13 +351,73 @@ void wxStackWalker::Walk(size_t skip) __except( WalkFrom((EXCEPTION_POINTERS *)GetExceptionInformation(), skip + 2), EXCEPTION_CONTINUE_EXECUTION ) { - // never executed because of WalkFromException() return value + // never executed because the above expression always evaluates to + // EXCEPTION_CONTINUE_EXECUTION } } #else // !wxUSE_DBGHELP -// TODO: implement stubs +// ============================================================================ +// stubs +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxStackFrame +// ---------------------------------------------------------------------------- + +void wxStackFrame::OnGetName() +{ +} + +void wxStackFrame::OnGetLocation() +{ +} + +bool +wxStackFrame::GetParam(size_t WXUNUSED(n), + wxString * WXUNUSED(type), + wxString * WXUNUSED(name), + wxString * WXUNUSED(value)) const +{ + return false; +} + +void wxStackFrame::OnParam(_SYMBOL_INFO * WXUNUSED(pSymInfo)) +{ +} + +void wxStackFrame::OnGetParam() +{ +} + +// ---------------------------------------------------------------------------- +// wxStackWalker +// ---------------------------------------------------------------------------- + +void +wxStackWalker::WalkFrom(const CONTEXT * WXUNUSED(pCtx), + size_t WXUNUSED(skip), + size_t WXUNUSED(maxDepth)) +{ +} + +void +wxStackWalker::WalkFrom(const _EXCEPTION_POINTERS * WXUNUSED(ep), + size_t WXUNUSED(skip), + size_t WXUNUSED(maxDepth)) +{ +} + +#if wxUSE_ON_FATAL_EXCEPTION +void wxStackWalker::WalkFromException(size_t WXUNUSED(maxDepth)) +{ +} +#endif // wxUSE_ON_FATAL_EXCEPTION + +void wxStackWalker::Walk(size_t WXUNUSED(skip), size_t WXUNUSED(maxDepth)) +{ +} #endif // wxUSE_DBGHELP/!wxUSE_DBGHELP