From ef219fce3947e76b657f84a0178174ea6dccd667 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Fri, 11 Jun 2004 07:09:43 +0000 Subject: [PATCH] small fixes preparing for arch/Threads --- stepmania/src/archutils/Unix/CrashHandler.cpp | 27 ++++++++++++++++++- stepmania/src/archutils/Unix/CrashHandler.h | 3 ++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/stepmania/src/archutils/Unix/CrashHandler.cpp b/stepmania/src/archutils/Unix/CrashHandler.cpp index 9b9dbb79ba..bc5c7e183d 100644 --- a/stepmania/src/archutils/Unix/CrashHandler.cpp +++ b/stepmania/src/archutils/Unix/CrashHandler.cpp @@ -307,6 +307,10 @@ static void RunCrashHandler( const CrashData *crash ) safe_print( fileno(stderr), "Fatal signal (", SignalName(crash->signal), ")", NULL ); break; + case CrashData::FORCE_CRASH_DEADLOCK: + safe_print( fileno(stderr), "Deadlock (", crash->reason, ")", NULL ); + break; + #if defined(DARWIN) case CrashData::OSX_EXCEPTION: safe_print( fileno(stderr), "Fatal exception (", ExceptionName( crash->kind ), ")", NULL ); @@ -367,6 +371,12 @@ static void RunCrashHandler( const CrashData *crash ) waitpid( childpid, &status, 0 ); /* We need to resume threads before continuing, or we may deadlock on _exit(). */ + /* XXX: race condition: If two threads are deadlocked on a pair of mutexes, there's + * a chance that they'll both try to lock the other's mutex at the same time. If + * that happens, then they'll both time out the lock at about the same time. One + * will trigger the deadlock crash first, and the other will be suspended. However, + * once we resume it here, it'll continue, and * trigger the deadlock crash again. + * It can result in unrecoverable deadlocks. */ RageThread::ResumeAllThreads(); if( WIFSIGNALED(status) ) @@ -388,7 +398,7 @@ void ForceCrashHandler( const char *reason ) RunCrashHandler( &crash ); } -void ForceCrashHandlerDeadlock( const char *reason, const BacktraceContext *ctx ) +void ForceCrashHandlerDeadlock( CString reason, const BacktraceContext *ctx ) { CrashData crash; memset( &crash, 0, sizeof(crash) ); @@ -403,6 +413,21 @@ void ForceCrashHandlerDeadlock( const char *reason, const BacktraceContext *ctx RunCrashHandler( &crash ); } +/* iCrashHandle comes from ThreadImpl_Pthreads::GetCrashHandle. */ +void ForceCrashHandlerDeadlock( CString reason, uint64_t iCrashHandle ) +{ + BacktraceContext ctx; + if( !GetThreadBacktraceContext( iCrashHandle, &ctx ) ) + { + reason += "; GetThreadBacktraceContext failed"; + ForceCrashHandler( reason ); + } else { + ForceCrashHandlerDeadlock( reason, &ctx ); + } + + _exit(1); +} + /* XXX test for recursive crashes here (eg. GetBacktrace crashing) */ void CrashSignalHandler( int signal, siginfo_t *si, const ucontext_t *uc ) diff --git a/stepmania/src/archutils/Unix/CrashHandler.h b/stepmania/src/archutils/Unix/CrashHandler.h index 6a10136e57..480e525c2b 100644 --- a/stepmania/src/archutils/Unix/CrashHandler.h +++ b/stepmania/src/archutils/Unix/CrashHandler.h @@ -3,7 +3,8 @@ void ForceCrashHandler( const char *reason ); struct BacktraceContext; -void ForceCrashHandlerDeadlock( const char *reason, const BacktraceContext *ctx ); +void ForceCrashHandlerDeadlock( CString reason, const BacktraceContext *ctx ); +void ForceCrashHandlerDeadlock( CString reason, uint64_t CrashHandle ); void CrashHandlerHandleArgs( int argc, char* argv[] ); void InitializeCrashHandler();