split out do_backtrace

This commit is contained in:
Glenn Maynard
2004-02-25 08:34:26 +00:00
parent 45591679e6
commit 5cb9970c4e
+60 -43
View File
@@ -624,39 +624,28 @@ static bool PointsToValidCall( unsigned long ptr )
return IsValidCall(buf+7, len); return IsValidCall(buf+7, len);
} }
static bool ReportCrashCallStack(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTERS *const pExc) static void do_backtrace( const void **buf, size_t size,
HANDLE hProcess, HANDLE hThread, const CONTEXT *pContext )
{ {
if (!g_debugInfo.pRVAHeap) {
Report(hwnd, hFile, "Could not open debug resource file (StepMania.vdi).");
return false;
}
if (g_debugInfo.nBuildNumber != int(version_num)) {
Report(hwnd, hFile, "Incorrect StepMania.vdi file (build %d, expected %d) for this version of StepMania -- call stack unavailable.", g_debugInfo.nBuildNumber, int(version_num));
return false;
}
// Retrieve stack pointers. // Retrieve stack pointers.
// Not sure if NtCurrentTeb() is available on Win95.... const char *pStackBase;
{
NT_TIB *pTib; LDT_ENTRY sel;
GetThreadSelectorEntry( hThread, pContext->SegFs, &sel );
__asm { const NT_TIB *tib = (NT_TIB *) ((sel.HighWord.Bits.BaseHi<<24)+(sel.HighWord.Bits.BaseMid<<16)+sel.BaseLow);
mov eax, fs:[0]_NT_TIB.Self const NT_TIB *pTib = tib->Self;
mov pTib, eax pStackBase = (char *)pTib->StackBase;
} }
char *pStackBase = (char *)pTib->StackBase; // Walk up the stack.
const CONTEXT *const pContext = (const CONTEXT *)pExc->ContextRecord;
const HANDLE hprMe = GetCurrentProcess();
const char *lpAddr = (const char *)pContext->Esp; const char *lpAddr = (const char *)pContext->Esp;
int limit = 100;
// Walk up the stack. Hopefully it wasn't fscked. const void *data = (void *) pContext->Eip;
size_t i = 0;
unsigned long data = pContext->Eip;
do { do {
if( i+1 >= size )
break;
bool fValid = true; bool fValid = true;
MEMORY_BASIC_INFORMATION meminfo; MEMORY_BASIC_INFORMATION meminfo;
@@ -665,44 +654,72 @@ static bool ReportCrashCallStack(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTE
if (!IsExecutableProtection(meminfo.Protect) || meminfo.State!=MEM_COMMIT) if (!IsExecutableProtection(meminfo.Protect) || meminfo.State!=MEM_COMMIT)
fValid = false; fValid = false;
if ( data != pContext->Eip && !PointsToValidCall(data) ) if ( data != (void *) pContext->Eip && !PointsToValidCall((unsigned long)data) )
fValid = false; fValid = false;
if (fValid) { if( fValid )
buf[i++] = data;
if (lpAddr >= pStackBase)
break;
lpAddr += 4;
} while( ReadProcessMemory(hProcess, lpAddr-4, &data, 4, NULL));
buf[i++] = NULL;
}
static bool ReportCrashCallStack( HWND hwnd, HANDLE hFile, const CONTEXT *pContext )
{
if( !g_debugInfo.pRVAHeap )
{
Report(hwnd, hFile, "Could not open debug resource file (StepMania.vdi).");
return false;
}
if( g_debugInfo.nBuildNumber != int(version_num) )
{
Report(hwnd, hFile, "Incorrect StepMania.vdi file (build %d, expected %d) for this version of StepMania -- call stack unavailable.", g_debugInfo.nBuildNumber, int(version_num));
return false;
}
#define BACKTRACE_MAX_SIZE 100
static const void *BacktracePointers[BACKTRACE_MAX_SIZE];
do_backtrace( BacktracePointers, BACKTRACE_MAX_SIZE, GetCurrentProcess(), GetCurrentThread(), pContext );
for( int i = 0; BacktracePointers[i]; ++i )
{
MEMORY_BASIC_INFORMATION meminfo;
VirtualQuery( BacktracePointers[i], &meminfo, sizeof meminfo );
char buf[512]; char buf[512];
if (VDDebugInfoLookupRVA(&g_debugInfo, data, buf, sizeof buf) >= 0) { if( VDDebugInfoLookupRVA(&g_debugInfo, (unsigned int)BacktracePointers[i], buf, sizeof(buf)) >= 0 )
Report(hwnd, hFile, "%08lx: %s", data, Demangle(buf)); {
--limit; Report(hwnd, hFile, "%08p: %s", BacktracePointers[i], Demangle(buf));
} else { } else {
char szName[MAX_PATH]; char szName[MAX_PATH];
if( !CrashGetModuleBaseName((HMODULE)meminfo.AllocationBase, szName) ) if( !CrashGetModuleBaseName((HMODULE)meminfo.AllocationBase, szName) )
strcpy( szName, "???" ); strcpy( szName, "???" );
DWORD64 disp; DWORD64 disp;
SYMBOL_INFO *pSymbol = GetSym( data, disp ); SYMBOL_INFO *pSymbol = GetSym( (unsigned int)BacktracePointers[i], disp );
if( pSymbol ) if( pSymbol )
{ {
Report(hwnd, hFile, "%08lx: %s!%s [%08lx+%lx+%lx]", Report(hwnd, hFile, "%08lx: %s!%s [%08lx+%lx+%lx]",
(unsigned long) data, szName, pSymbol->Name, (unsigned long) BacktracePointers[i], szName, pSymbol->Name,
(unsigned long) meminfo.AllocationBase, (unsigned long) meminfo.AllocationBase,
(unsigned long) (pSymbol->Address) - (unsigned long) (meminfo.AllocationBase), (unsigned long) (pSymbol->Address) - (unsigned long) (meminfo.AllocationBase),
(unsigned long) disp); (unsigned long) disp);
} else { } else {
Report(hwnd, hFile, "%08lx: %s!%08lx", Report(hwnd, hFile, "%08lx: %s!%08lx",
(unsigned long) data, szName, (unsigned long) BacktracePointers[i], szName,
(unsigned long) meminfo.AllocationBase ); (unsigned long) meminfo.AllocationBase );
} }
--limit;
} }
} }
if (lpAddr >= pStackBase)
break;
lpAddr += 4;
} while(limit > 0 && ReadProcessMemory(hprMe, lpAddr-4, &data, 4, NULL));
return true; return true;
} }
@@ -734,7 +751,7 @@ static void DoSave(const EXCEPTION_POINTERS *pExc)
WriteBuf( hFile, Checkpoints::GetLogs("\r\n") ); WriteBuf( hFile, Checkpoints::GetLogs("\r\n") );
Report(NULL, hFile, ""); Report(NULL, hFile, "");
ReportCrashCallStack(NULL, hFile, pExc); ReportCrashCallStack( NULL, hFile, pExc->ContextRecord );
Report(NULL, hFile, ""); Report(NULL, hFile, "");
Report(NULL, hFile, "Static log:"); Report(NULL, hFile, "Static log:");
@@ -797,7 +814,7 @@ BOOL APIENTRY CrashDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
SendMessage(hwndList, WM_SETFONT, (WPARAM)hFontMono, MAKELPARAM(TRUE, 0)); SendMessage(hwndList, WM_SETFONT, (WPARAM)hFontMono, MAKELPARAM(TRUE, 0));
ReportReason(hwndReason, NULL, pExc); ReportReason(hwndReason, NULL, pExc);
s_bHaveCallstack = ReportCrashCallStack(hwndList, NULL, pExc); s_bHaveCallstack = ReportCrashCallStack( hwndList, NULL, pExc->ContextRecord );
} }
return TRUE; return TRUE;