From 8de73a718e264d39ac490cab69366fec3497e83a Mon Sep 17 00:00:00 2001 From: Daniel Stien Date: Sat, 23 Aug 2008 02:48:38 +0000 Subject: [PATCH] Print stack trace on exceptions in debug mode. Workaround for time_t* cast failure in XBE dump. Custom version string suffix. --- build/win32/CxbxKrnl.vcproj | 2 +- src/Common/Xbe.cpp | 11 +++-- src/Cxbx.h | 4 +- src/CxbxKrnl/Emu.cpp | 91 +++++++++++++++++++++++++++++++++++++ src/CxbxKrnl/Emu.h | 5 ++ 5 files changed, 106 insertions(+), 7 deletions(-) diff --git a/build/win32/CxbxKrnl.vcproj b/build/win32/CxbxKrnl.vcproj index 88a8953e4..57fbe30e1 100755 --- a/build/win32/CxbxKrnl.vcproj +++ b/build/win32/CxbxKrnl.vcproj @@ -170,7 +170,7 @@ /> +CRITICAL_SECTION dbgCritical; +#endif + // Global Variable(s) HANDLE g_hCurDir = NULL; CHAR *g_strCurDrive= NULL; @@ -83,6 +88,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) if(fdwReason == DLL_PROCESS_ATTACH) { +#ifdef _DEBUG + InitializeCriticalSection(&dbgCritical); +#endif + EmuShared::Init(); hInitInstance = hinstDLL; } @@ -91,6 +100,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if(hInitInstance == hinstDLL) EmuShared::Cleanup(); + +#ifdef _DEBUG + DeleteCriticalSection(&dbgCritical); +#endif } return TRUE; @@ -268,6 +281,11 @@ extern int EmuException(LPEXCEPTION_POINTERS e) e->ContextRecord->Eip, e->ContextRecord->EFlags, e->ContextRecord->Eax, e->ContextRecord->Ebx, e->ContextRecord->Ecx, e->ContextRecord->Edx, e->ContextRecord->Esi, e->ContextRecord->Edi, e->ContextRecord->Esp, e->ContextRecord->Ebp); + +#ifdef _DEBUG + CONTEXT Context = *(e->ContextRecord); + EmuPrintStackTrace(&Context); +#endif } fflush(stdout); @@ -393,3 +411,76 @@ int ExitException(LPEXCEPTION_POINTERS e) return EXCEPTION_CONTINUE_SEARCH; } + +#ifdef _DEBUG +// print call stack trace +void EmuPrintStackTrace(PCONTEXT ContextRecord) +{ + static int const STACK_MAX = 16; + static int const SYMBOL_MAXLEN = 64; + + EnterCriticalSection(&dbgCritical); + + IMAGEHLP_MODULE64 module = { sizeof(IMAGEHLP_MODULE) }; + + BOOL fSymInitialized; + fSymInitialized = SymInitialize(GetCurrentProcess(), NULL, TRUE); + + STACKFRAME64 frame = { sizeof(STACKFRAME64) }; + frame.AddrPC.Offset = ContextRecord->Eip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = ContextRecord->Ebp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Offset = ContextRecord->Esp; + frame.AddrStack.Mode = AddrModeFlat; + + for(int i = 0; i < STACK_MAX; i++) + { + if(!StackWalk64( + IMAGE_FILE_MACHINE_I386, + GetCurrentProcess(), + GetCurrentThread(), + &frame, + ContextRecord, + NULL, + SymFunctionTableAccess64, + SymGetModuleBase64, + NULL)) + break; + + DWORD64 dwDisplacement = 0; + PSYMBOL_INFO pSymbol = 0; + BYTE symbol[sizeof(SYMBOL_INFO) + SYMBOL_MAXLEN]; + + SymGetModuleInfo64(GetCurrentProcess(), frame.AddrPC.Offset, &module); + + if(fSymInitialized) + { + pSymbol = (PSYMBOL_INFO)symbol; + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO) + SYMBOL_MAXLEN - 1; + pSymbol->MaxNameLen = SYMBOL_MAXLEN; + + if(!SymFromAddr(GetCurrentProcess(), frame.AddrPC.Offset, &dwDisplacement, pSymbol)) + pSymbol = 0; + } + + if(module.ModuleName) + printf(" %2d: %-8s 0x%.08X", i, module.ModuleName, frame.AddrPC.Offset); + else + printf(" %2d: %8c 0x%.08X", i, ' ', frame.AddrPC.Offset); + + if(pSymbol) + { + printf(" %s+0x%.04X\n", pSymbol->Name, dwDisplacement); + } + else + printf("\n"); + } + printf("\n"); + + if(fSymInitialized) + SymCleanup(GetCurrentProcess()); + + LeaveCriticalSection(&dbgCritical); +} +#endif diff --git a/src/CxbxKrnl/Emu.h b/src/CxbxKrnl/Emu.h index cb22bc811..4e7d6d353 100644 --- a/src/CxbxKrnl/Emu.h +++ b/src/CxbxKrnl/Emu.h @@ -53,6 +53,11 @@ extern int EmuException(LPEXCEPTION_POINTERS e); // check the allocation size of a given virtual address extern int EmuCheckAllocationSize(LPVOID pBase, bool largeBound); +// print call stack trace +#ifdef _DEBUG +void EmuPrintStackTrace(PCONTEXT ContextRecord); +#endif + // global flags specifying current emulation state extern volatile bool g_bEmuException; extern volatile bool g_bEmuSuspended;