split out do_backtrace

This commit is contained in:
Glenn Maynard
2004-02-25 08:34:26 +00:00
parent 45591679e6
commit 5cb9970c4e
+75 -58
View File
@@ -624,39 +624,28 @@ static bool PointsToValidCall( unsigned long ptr )
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.
// Not sure if NtCurrentTeb() is available on Win95....
NT_TIB *pTib;
__asm {
mov eax, fs:[0]_NT_TIB.Self
mov pTib, eax
const char *pStackBase;
{
LDT_ENTRY sel;
GetThreadSelectorEntry( hThread, pContext->SegFs, &sel );
const NT_TIB *tib = (NT_TIB *) ((sel.HighWord.Bits.BaseHi<<24)+(sel.HighWord.Bits.BaseMid<<16)+sel.BaseLow);
const NT_TIB *pTib = tib->Self;
pStackBase = (char *)pTib->StackBase;
}
char *pStackBase = (char *)pTib->StackBase;
const CONTEXT *const pContext = (const CONTEXT *)pExc->ContextRecord;
const HANDLE hprMe = GetCurrentProcess();
// Walk up the stack.
const char *lpAddr = (const char *)pContext->Esp;
int limit = 100;
// Walk up the stack. Hopefully it wasn't fscked.
unsigned long data = pContext->Eip;
const void *data = (void *) pContext->Eip;
size_t i = 0;
do {
if( i+1 >= size )
break;
bool fValid = true;
MEMORY_BASIC_INFORMATION meminfo;
@@ -665,43 +654,71 @@ static bool ReportCrashCallStack(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTE
if (!IsExecutableProtection(meminfo.Protect) || meminfo.State!=MEM_COMMIT)
fValid = false;
if ( data != pContext->Eip && !PointsToValidCall(data) )
if ( data != (void *) pContext->Eip && !PointsToValidCall((unsigned long)data) )
fValid = false;
if (fValid) {
char buf[512];
if (VDDebugInfoLookupRVA(&g_debugInfo, data, buf, sizeof buf) >= 0) {
Report(hwnd, hFile, "%08lx: %s", data, Demangle(buf));
--limit;
} else {
char szName[MAX_PATH];
if( !CrashGetModuleBaseName((HMODULE)meminfo.AllocationBase, szName) )
strcpy( szName, "???" );
DWORD64 disp;
SYMBOL_INFO *pSymbol = GetSym( data, disp );
if( pSymbol )
{
Report(hwnd, hFile, "%08lx: %s!%s [%08lx+%lx+%lx]",
(unsigned long) data, szName, pSymbol->Name,
(unsigned long) meminfo.AllocationBase,
(unsigned long) (pSymbol->Address) - (unsigned long) (meminfo.AllocationBase),
(unsigned long) disp);
} else {
Report(hwnd, hFile, "%08lx: %s!%08lx",
(unsigned long) data, szName,
(unsigned long) meminfo.AllocationBase );
}
--limit;
}
}
if( fValid )
buf[i++] = data;
if (lpAddr >= pStackBase)
break;
lpAddr += 4;
} while(limit > 0 && ReadProcessMemory(hprMe, lpAddr-4, &data, 4, NULL));
} 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];
if( VDDebugInfoLookupRVA(&g_debugInfo, (unsigned int)BacktracePointers[i], buf, sizeof(buf)) >= 0 )
{
Report(hwnd, hFile, "%08p: %s", BacktracePointers[i], Demangle(buf));
} else {
char szName[MAX_PATH];
if( !CrashGetModuleBaseName((HMODULE)meminfo.AllocationBase, szName) )
strcpy( szName, "???" );
DWORD64 disp;
SYMBOL_INFO *pSymbol = GetSym( (unsigned int)BacktracePointers[i], disp );
if( pSymbol )
{
Report(hwnd, hFile, "%08lx: %s!%s [%08lx+%lx+%lx]",
(unsigned long) BacktracePointers[i], szName, pSymbol->Name,
(unsigned long) meminfo.AllocationBase,
(unsigned long) (pSymbol->Address) - (unsigned long) (meminfo.AllocationBase),
(unsigned long) disp);
} else {
Report(hwnd, hFile, "%08lx: %s!%08lx",
(unsigned long) BacktracePointers[i], szName,
(unsigned long) meminfo.AllocationBase );
}
}
}
return true;
}
@@ -734,7 +751,7 @@ static void DoSave(const EXCEPTION_POINTERS *pExc)
WriteBuf( hFile, Checkpoints::GetLogs("\r\n") );
Report(NULL, hFile, "");
ReportCrashCallStack(NULL, hFile, pExc);
ReportCrashCallStack( NULL, hFile, pExc->ContextRecord );
Report(NULL, hFile, "");
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));
ReportReason(hwndReason, NULL, pExc);
s_bHaveCallstack = ReportCrashCallStack(hwndList, NULL, pExc);
s_bHaveCallstack = ReportCrashCallStack( hwndList, NULL, pExc->ContextRecord );
}
return TRUE;