slight unification of crash apis; better .vdi searching
This commit is contained in:
@@ -606,7 +606,8 @@ void RageMutexImpl::Lock()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ThreadSlot *slot = FindThread( LockedBy );
|
ThreadSlot *slot = FindThread( LockedBy );
|
||||||
Crash_BacktraceThread( slot? slot->ThreadHandle:NULL );
|
ForceCrashHandlerDeadlock( ssprintf("Thread deadlock on mutex %s", m_Parent->GetName().c_str()),
|
||||||
|
slot? slot->ThreadHandle:NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RageMutexImpl::Unlock()
|
void RageMutexImpl::Unlock()
|
||||||
|
|||||||
@@ -60,6 +60,16 @@ extern HINSTANCE g_hInstance;
|
|||||||
#define new not_allowed_here
|
#define new not_allowed_here
|
||||||
|
|
||||||
|
|
||||||
|
static void GetVDIPath( char *buf, int bufsiz )
|
||||||
|
{
|
||||||
|
GetModuleFileName( NULL, buf, bufsiz );
|
||||||
|
buf[bufsiz-5] = 0;
|
||||||
|
char *p = strrchr( buf, '.' );
|
||||||
|
if( p )
|
||||||
|
strcpy( p, ".vdi" );
|
||||||
|
else
|
||||||
|
strcat( buf, ".vdi" );
|
||||||
|
}
|
||||||
|
|
||||||
static void SpliceProgramPath(char *buf, int bufsiz, const char *fn) {
|
static void SpliceProgramPath(char *buf, int bufsiz, const char *fn) {
|
||||||
char tbuf[MAX_PATH];
|
char tbuf[MAX_PATH];
|
||||||
@@ -84,6 +94,7 @@ struct VDDebugInfoContext
|
|||||||
const char *pFuncNameHeap;
|
const char *pFuncNameHeap;
|
||||||
const unsigned long (*pSegments)[2];
|
const unsigned long (*pSegments)[2];
|
||||||
int nSegments;
|
int nSegments;
|
||||||
|
char sFilename[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -474,13 +485,12 @@ bool VDDebugInfoInitFromFile( VDDebugInfoContext *pctx )
|
|||||||
if( pctx->Loaded() )
|
if( pctx->Loaded() )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
char pszFilename[1024];
|
GetVDIPath( pctx->sFilename, sizeof(pctx->sFilename) );
|
||||||
SpliceProgramPath(pszFilename, sizeof(pszFilename), "StepMania.vdi");
|
|
||||||
|
|
||||||
pctx->pRawBlock = NULL;
|
pctx->pRawBlock = NULL;
|
||||||
pctx->pRVAHeap = NULL;
|
pctx->pRVAHeap = NULL;
|
||||||
|
|
||||||
HANDLE h = CreateFile(pszFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
HANDLE h = CreateFile(pctx->sFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
if (INVALID_HANDLE_VALUE == h)
|
if (INVALID_HANDLE_VALUE == h)
|
||||||
return false;
|
return false;
|
||||||
@@ -745,13 +755,14 @@ static bool ReportCallStack( HWND hwnd, HANDLE hFile, const void **Backtrace )
|
|||||||
VDDebugInfoInitFromFile( &g_debugInfo );
|
VDDebugInfoInitFromFile( &g_debugInfo );
|
||||||
if( !g_debugInfo.Loaded() )
|
if( !g_debugInfo.Loaded() )
|
||||||
{
|
{
|
||||||
Report(hwnd, hFile, "Could not open debug resource file (StepMania.vdi).");
|
Report( hwnd, hFile, "Could not open debug resource file (%s).", g_debugInfo.sFilename );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( g_debugInfo.nBuildNumber != int(version_num) )
|
if( g_debugInfo.nBuildNumber != int(version_num) )
|
||||||
{
|
{
|
||||||
Report(hwnd, hFile, "Incorrect StepMania.vdi file (build %d, expected %d) for this version of " PRODUCT_NAME " -- call stack unavailable.", g_debugInfo.nBuildNumber, int(version_num));
|
Report(hwnd, hFile, "Incorrect %s file (build %d, expected %d) for this version of " PRODUCT_NAME " -- call stack unavailable.",
|
||||||
|
g_debugInfo.sFilename, g_debugInfo.nBuildNumber, int(version_num));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -938,41 +949,30 @@ void NORETURN debug_crash()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get a stack trace of the current thread and the specified thread. */
|
/* Get a stack trace of the current thread and the specified thread. */
|
||||||
void NORETURN Crash_BacktraceThread( HANDLE hThread )
|
void ForceCrashHandlerDeadlock( const char *reason, HANDLE hThread )
|
||||||
{
|
{
|
||||||
|
strncpy( g_CrashInfo.m_CrashReason, reason, sizeof(g_CrashInfo.m_CrashReason) );
|
||||||
|
g_CrashInfo.m_CrashReason[ sizeof(g_CrashInfo.m_CrashReason)-1 ] = 0;
|
||||||
|
|
||||||
if( hThread == NULL )
|
if( hThread == NULL )
|
||||||
{
|
{
|
||||||
strcpy( g_CrashInfo.m_CrashReason, "Crash reason: Thread deadlock (with NULL?)" );
|
strcat( g_CrashInfo.m_CrashReason, "(hThread == NULL)" );
|
||||||
debug_crash();
|
} else {
|
||||||
|
/* Suspend the other thread we're going to backtrace. (We need to at least suspend
|
||||||
|
* hThread, for GetThreadContext to work.) */
|
||||||
|
RageThread::HaltAllThreads( false );
|
||||||
|
|
||||||
|
CONTEXT context;
|
||||||
|
context.ContextFlags = CONTEXT_FULL;
|
||||||
|
if( !GetThreadContext( hThread, &context ) )
|
||||||
|
strcat( g_CrashInfo.m_CrashReason, "(GetThreadContext failed)" );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static const void *BacktracePointers[BACKTRACE_MAX_SIZE];
|
||||||
|
do_backtrace( g_CrashInfo.m_AlternateThreadBacktrace, BACKTRACE_MAX_SIZE, GetCurrentProcess(), hThread, &context );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Ugh. GetThreadId is XP-only or 2003 Server-only or something. How can we do this? */
|
|
||||||
if( GetThreadId( hThread ) == GetCurrentThreadId() )
|
|
||||||
{
|
|
||||||
/* hThread is the current thread. This shouldn't happen. */
|
|
||||||
strcpy( g_CrashInfo.m_CrashReason, "Crash reason: Thread deadlock (with the current thread?)" );
|
|
||||||
debug_crash();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Suspend the other thread we're going to backtrace. (We need to at least suspend
|
|
||||||
* hThread, for GetThreadContext to work.) */
|
|
||||||
RageThread::HaltAllThreads( false );
|
|
||||||
// SuspendThread( hThread );
|
|
||||||
|
|
||||||
CONTEXT context;
|
|
||||||
context.ContextFlags = CONTEXT_FULL;
|
|
||||||
if( !GetThreadContext( hThread, &context ) )
|
|
||||||
{
|
|
||||||
strcpy( g_CrashInfo.m_CrashReason, "Crash reason: Thread deadlock (GetThreadContext failed)" );
|
|
||||||
debug_crash();
|
|
||||||
}
|
|
||||||
|
|
||||||
static const void *BacktracePointers[BACKTRACE_MAX_SIZE];
|
|
||||||
do_backtrace( g_CrashInfo.m_AlternateThreadBacktrace, BACKTRACE_MAX_SIZE, GetCurrentProcess(), hThread, &context );
|
|
||||||
|
|
||||||
strcpy( g_CrashInfo.m_CrashReason, "Crash reason: Thread deadlock" );
|
|
||||||
debug_crash();
|
debug_crash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,6 @@ void NORETURN debug_crash();
|
|||||||
void do_backtrace( const void **buf, size_t size, HANDLE hProcess, HANDLE hThread, const CONTEXT *pContext );
|
void do_backtrace( const void **buf, size_t size, HANDLE hProcess, HANDLE hThread, const CONTEXT *pContext );
|
||||||
void SymLookup( const void *ptr, char *buf );
|
void SymLookup( const void *ptr, char *buf );
|
||||||
void ForceCrashHandler( const char *reason );
|
void ForceCrashHandler( const char *reason );
|
||||||
void NORETURN Crash_BacktraceThread( HANDLE hThread );
|
void ForceCrashHandlerDeadlock( const char *reason, HANDLE hThread );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user