- Output(_T("Fault address: %08x %02x:%08x %s\r\n"),
- pExceptionAddress, section, offset, szFaultingModule);
-
-#ifdef _M_IX86
- // Show the registers
- Output( _T("\r\nRegisters:\r\n") );
-
- Output(_T("EAX: %08x EBX: %08x ECX: %08x EDX: %08x ESI: %08x EDI: %08x\r\n"),
- pCtx->Eax, pCtx->Ebx, pCtx->Ecx, pCtx->Edx, pCtx->Esi, pCtx->Edi);
-
- Output(_T("CS:EIP: %04x:%08x SS:ESP: %04x:%08x EBP: %08x\r\n"),
- pCtx->SegCs, pCtx->Eip, pCtx->SegSs, pCtx->Esp, pCtx->Ebp );
- Output(_T("DS: %04x ES: %04x FS: %04x GS: %04x\r\n"),
- pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs);
- Output(_T("Flags: %08x\r\n"), pCtx->EFlags );
-#endif // _M_IX86
-
- return ::GetModuleHandle(szFaultingModule);
-}
-
-void wxCrashReportImpl::OutputStack(const CONTEXT *pCtx, int flags)
-{
- enum
- {
- Output_Stack,
- Output_Locals,
- Output_Max
-#ifndef _M_IX86
- // can't show locals under other architectures
- = Output_Locals
-#endif
- };
-
- for ( int step = 0; step < Output_Max; step++ )
- {
- // don't do things we're not asked for
- if ( (step == Output_Stack) && !(flags & wxCRASH_REPORT_STACK) ||
- (step == Output_Locals) && !(flags & wxCRASH_REPORT_LOCALS) )
- {
- continue;
- }
-
- // the context is going to be modified below so make a copy
- CONTEXT ctx = *pCtx;
-
- Output(_T("\r\n%s\r\n")
- _T(" # Address Frame Function SourceFile\r\n"),
- step == Output_Stack ? _T("Call stack") : _T("Local variables"));
-
- DWORD dwMachineType = 0;
-
- STACKFRAME sf;
- wxZeroMemory(sf);
-
-#ifdef _M_IX86
- // Initialize the STACKFRAME structure for the first call. This is
- // only necessary for Intel CPUs, and isn't mentioned in the
- // documentation.
- sf.AddrPC.Offset = ctx.Eip;
- sf.AddrPC.Mode = AddrModeFlat;
- sf.AddrStack.Offset = ctx.Esp;
- sf.AddrStack.Mode = AddrModeFlat;
- sf.AddrFrame.Offset = ctx.Ebp;
- sf.AddrFrame.Mode = AddrModeFlat;
-
- dwMachineType = IMAGE_FILE_MACHINE_I386;
-#endif // _M_IX86
-
- const HANDLE hProcess = GetCurrentProcess();
- const HANDLE hThread = GetCurrentThread();
-
- // first show just the call stack
- int frame = 0;
- for ( ;; )
- {
- // Get the next stack frame
- if ( !StackWalk(dwMachineType,
- hProcess,
- hThread,
- &sf,
- &ctx,
- 0,
- SymFunctionTableAccess,
- SymGetModuleBase,
- 0) )
- {
- break;
- }
-
- // Basic sanity check to make sure the frame is OK.
- if ( !sf.AddrFrame.Offset )
- break;
-
- Output(_T("%2d %08x %08x "),
- frame++, sf.AddrPC.Offset, sf.AddrFrame.Offset);
-
- // Get the name of the function for this stack frame entry
- BYTE symbolBuffer[ sizeof(SYMBOL_INFO) + 1024 ];
- PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
- pSymbol->SizeOfStruct = sizeof(symbolBuffer);
- pSymbol->MaxNameLen = 1024;
-
- // Displacement of the input address, relative to the start of the
- // symbol
- DWORD64 symDisplacement = 0;
-
- if ( SymFromAddr(hProcess, sf.AddrPC.Offset,
- &symDisplacement,pSymbol) )
- {
- Output(_T("%hs()+%#") wxLongLongFmtSpec _T("x"),
- pSymbol->Name, symDisplacement);
- }
- else // No symbol found. Print out the logical address instead.
- {
- TCHAR szModule[MAX_PATH];
- DWORD section,
- offset;
-
- if ( !GetLogicalAddress((PVOID)sf.AddrPC.Offset,
- szModule, sizeof(szModule),
- section, offset) )
- {
- szModule[0] = _T('\0');
- section =
- offset = 0;
- }
-
- Output(_T("%04x:%08x %s"), section, offset, szModule);
- }
-
- // Get the source line for this stack frame entry
- IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
- DWORD dwLineDisplacement;
- if ( SymGetLineFromAddr(hProcess, sf.AddrPC.Offset,
- &dwLineDisplacement, &lineInfo ))
- {
- Output(_T(" %s line %u"),
- lineInfo.FileName, lineInfo.LineNumber);
- }
-
- OutputEndl();
-
-
-#ifdef _M_IX86
- // on the second iteration also show the local variables and
- // parameters
- if ( step == Output_Locals )
- {
- // Use SymSetContext to get just the locals/params for this
- // frame
- IMAGEHLP_STACK_FRAME imagehlpStackFrame;
- imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset;
- SymSetContext(hProcess, &imagehlpStackFrame, 0);
-
- // Enumerate the locals/parameters
- m_sfCurrent = &sf;
- SymEnumSymbols(hProcess, 0, 0, EnumerateSymbolsCallback, this);
-
- OutputEndl();
- }
-#endif // _M_IX86
- }
- }