Print stack trace on exceptions in debug mode.

Workaround for time_t* cast failure in XBE dump.

Custom version string suffix.
This commit is contained in:
Daniel Stien 2008-08-23 02:48:38 +00:00
parent 1872177ff1
commit 8de73a718e
5 changed files with 106 additions and 7 deletions

View File

@ -170,7 +170,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib dsound.lib winmm.lib ddraw.lib d3dx8.lib d3d8.lib dinput8.lib dxguid.lib odbc32.lib odbccp32.lib"
AdditionalDependencies="ws2_32.lib dsound.lib winmm.lib ddraw.lib d3dx8.lib d3d8.lib dinput8.lib dxguid.lib odbc32.lib odbccp32.lib dbghelp.lib"
OutputFile=".\..\..\bin\debug/CxbxKrnl.dll"
LinkIncremental="2"
SuppressStartupBanner="true"

View File

@ -1007,8 +1007,11 @@ void Xbe::ConstructorInit()
}
// better time
static char *BetterTime(char *x_ctime)
static char *BetterTime(uint32 x_timeDate)
{
time_t x_time = x_timeDate;
char *x_ctime = ctime(&x_time);
int v=0;
for(v=0;x_ctime[v] != '\n';v++);
@ -1048,7 +1051,7 @@ void Xbe::DumpInformation(FILE *x_file)
fprintf(x_file, "Size of Headers : 0x%.08X\n", m_Header.dwSizeofHeaders);
fprintf(x_file, "Size of Image : 0x%.08X\n", m_Header.dwSizeofImage);
fprintf(x_file, "Size of Image Header : 0x%.08X\n", m_Header.dwSizeofImageHeader);
fprintf(x_file, "TimeDate Stamp : 0x%.08X (%s)\n", m_Header.dwTimeDate, BetterTime(ctime((const time_t*)&m_Header.dwTimeDate)));
fprintf(x_file, "TimeDate Stamp : 0x%.08X (%s)\n", m_Header.dwTimeDate, BetterTime(m_Header.dwTimeDate));
fprintf(x_file, "Certificate Address : 0x%.08X\n", m_Header.dwCertificateAddr);
fprintf(x_file, "Number of Sections : 0x%.08X\n", m_Header.dwSections);
fprintf(x_file, "Section Headers Address : 0x%.08X\n", m_Header.dwSectionHeadersAddr);
@ -1091,7 +1094,7 @@ void Xbe::DumpInformation(FILE *x_file)
fprintf(x_file, "(PE) Base Address : 0x%.08X\n", m_Header.dwPeBaseAddr);
fprintf(x_file, "(PE) Size of Image : 0x%.08X\n", m_Header.dwPeSizeofImage);
fprintf(x_file, "(PE) Checksum : 0x%.08X\n", m_Header.dwPeChecksum);
fprintf(x_file, "(PE) TimeDate Stamp : 0x%.08X (%s)\n", m_Header.dwPeTimeDate, BetterTime(ctime((time_t*)&m_Header.dwPeTimeDate)));
fprintf(x_file, "(PE) TimeDate Stamp : 0x%.08X (%s)\n", m_Header.dwPeTimeDate, BetterTime(m_Header.dwPeTimeDate));
fprintf(x_file, "Debug Pathname Address : 0x%.08X (\"%s\")\n", m_Header.dwDebugPathnameAddr, GetAddr(m_Header.dwDebugPathnameAddr));
fprintf(x_file, "Debug Filename Address : 0x%.08X (\"%s\")\n", m_Header.dwDebugFilenameAddr, GetAddr(m_Header.dwDebugFilenameAddr));
fprintf(x_file, "Debug Unicode filename Address : 0x%.08X (L\"%s\")\n", m_Header.dwDebugUnicodeFilenameAddr, AsciiFilename);
@ -1107,7 +1110,7 @@ void Xbe::DumpInformation(FILE *x_file)
fprintf(x_file, "Dumping XBE Certificate...\n");
fprintf(x_file, "\n");
fprintf(x_file, "Size of Certificate : 0x%.08X\n", m_Certificate.dwSize);
fprintf(x_file, "TimeDate Stamp : 0x%.08X (%s)\n", m_Certificate.dwTimeDate, BetterTime(ctime((time_t*)&m_Certificate.dwTimeDate)));
fprintf(x_file, "TimeDate Stamp : 0x%.08X (%s)\n", m_Certificate.dwTimeDate, BetterTime(m_Certificate.dwTimeDate));
fprintf(x_file, "Title ID : 0x%.08X\n", m_Certificate.dwTitleId);
fprintf(x_file, "Title : L\"%s\"\n", m_szAsciiTitle);

View File

@ -76,9 +76,9 @@ typedef signed long sint32;
/*! version string dependent on trace flag */
#ifndef _DEBUG_TRACE
#define _CXBX_VERSION "0.8.0"
#define _CXBX_VERSION "0.8.0-ds"
#else
#define _CXBX_VERSION "0.8.0-Trace"
#define _CXBX_VERSION "0.8.0-ds-Trace"
#endif
/*! debug mode choices */

View File

@ -57,6 +57,11 @@ namespace NtDll
#include "HLEDataBase.h"
#include "HLEIntercept.h"
#ifdef _DEBUG
#include <Dbghelp.h>
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

View File

@ -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;