diff --git a/stepmania/src/archutils/Unix/CrashHandler.cpp b/stepmania/src/archutils/Unix/CrashHandler.cpp index a74f033059..4e94e886b7 100644 --- a/stepmania/src/archutils/Unix/CrashHandler.cpp +++ b/stepmania/src/archutils/Unix/CrashHandler.cpp @@ -280,12 +280,8 @@ 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; - - case CrashData::FORCE_CRASH_THIS_THREAD: - safe_print( fileno(stderr), "Crash handler failed an assertion: \"", crash->reason, "\"", NULL ); + case CrashData::FORCE_CRASH: + safe_print( fileno(stderr), "Crash handler failed: \"", crash->reason, "\"", NULL ); break; default: @@ -357,34 +353,18 @@ void ForceCrashHandler( const char *reason ) CrashData crash; memset( &crash, 0, sizeof(crash) ); - crash.type = CrashData::FORCE_CRASH_THIS_THREAD; + crash.type = CrashData::FORCE_CRASH; strncpy( crash.reason, reason, sizeof(crash.reason) ); crash.reason[ sizeof(crash.reason)-1 ] = 0; - GetBacktrace( crash.BacktracePointers, BACKTRACE_MAX_SIZE, NULL ); + GetBacktrace( crash.BacktracePointers[0], BACKTRACE_MAX_SIZE, NULL ); RunCrashHandler( &crash ); } -void ForceCrashHandlerDeadlock( const CString& reason, const BacktraceContext *ctx ) +void ForceCrashHandlerDeadlock( CString reason, uint64_t iID ) { - CrashData crash; - memset( &crash, 0, sizeof(crash) ); - - crash.type = CrashData::FORCE_CRASH_DEADLOCK; - strncpy( crash.reason, reason, min(sizeof(crash.reason) - 1, reason.length()) ); - crash.reason[ sizeof(crash.reason)-1 ] = 0; - - GetBacktrace( crash.BacktracePointers, BACKTRACE_MAX_SIZE, NULL ); - GetBacktrace( crash.BacktracePointers2, BACKTRACE_MAX_SIZE, ctx ); - - RunCrashHandler( &crash ); -} - -/* iCrashHandle comes from ThreadImpl_Pthreads::GetThreadId. */ -void ForceCrashHandlerDeadlock( CString reason, uint64_t iCrashHandle ) -{ - if ( iCrashHandle == GetInvalidThreadId() ) + if ( iID == GetInvalidThreadId() ) { ForceCrashHandler( reason ); _exit(1); @@ -399,13 +379,25 @@ void ForceCrashHandlerDeadlock( CString reason, uint64_t iCrashHandle ) #if defined(DARWIN) SuspendThread(iCrashHandle); #endif - if( !GetThreadBacktraceContext( iCrashHandle, &ctx ) ) - { + CrashData crash; + memset( &crash, 0, sizeof(crash) ); + + crash.type = CrashData::FORCE_CRASH; + + GetBacktrace( crash.BacktracePointers[0], BACKTRACE_MAX_SIZE, NULL ); + + if( !GetThreadBacktraceContext( iID, &ctx ) ) reason += "; GetThreadBacktraceContext failed"; - ForceCrashHandler( reason ); - } else - ForceCrashHandlerDeadlock( reason, &ctx ); + GetBacktrace( crash.BacktracePointers[1], BACKTRACE_MAX_SIZE, &ctx ); + + strncpy( crash.m_ThreadName[0], RageThread::GetCurThreadName(), sizeof(crash.m_ThreadName[0])-1 ); + strncpy( crash.m_ThreadName[1], RageThread::GetThreadNameByID(iID), sizeof(crash.m_ThreadName[0])-1 ); + + strncpy( crash.reason, reason, min(sizeof(crash.reason) - 1, reason.length()) ); + crash.reason[ sizeof(crash.reason)-1 ] = 0; + + RunCrashHandler( &crash ); _exit(1); } @@ -423,7 +415,9 @@ void CrashSignalHandler( int signal, siginfo_t *si, const ucontext_t *uc ) BacktraceContext ctx; GetSignalBacktraceContext( &ctx, uc ); - GetBacktrace( crash.BacktracePointers, BACKTRACE_MAX_SIZE, &ctx ); + GetBacktrace( crash.BacktracePointers[0], BACKTRACE_MAX_SIZE, &ctx ); + + strncpy( crash.m_ThreadName[0], RageThread::GetCurThreadName(), sizeof(crash.m_ThreadName[0])-1 ); RunCrashHandler( &crash ); } diff --git a/stepmania/src/archutils/Unix/CrashHandler.h b/stepmania/src/archutils/Unix/CrashHandler.h index 5900d49f9f..232affdfeb 100644 --- a/stepmania/src/archutils/Unix/CrashHandler.h +++ b/stepmania/src/archutils/Unix/CrashHandler.h @@ -3,7 +3,6 @@ void ForceCrashHandler( const char *reason ); struct BacktraceContext; -void ForceCrashHandlerDeadlock( const CString& reason, const BacktraceContext *ctx ); void ForceCrashHandlerDeadlock( CString reason, uint64_t CrashHandle ); void CrashHandlerHandleArgs( int argc, char* argv[] ); void InitializeCrashHandler(); diff --git a/stepmania/src/archutils/Unix/CrashHandlerChild.cpp b/stepmania/src/archutils/Unix/CrashHandlerChild.cpp index 984cd283c9..ae5ae757a3 100644 --- a/stepmania/src/archutils/Unix/CrashHandlerChild.cpp +++ b/stepmania/src/archutils/Unix/CrashHandlerChild.cpp @@ -307,8 +307,7 @@ static void child_process() } break; } - case CrashData::FORCE_CRASH_THIS_THREAD: - case CrashData::FORCE_CRASH_DEADLOCK: + case CrashData::FORCE_CRASH: crash.reason[ sizeof(crash.reason)-1] = 0; reason = crash.reason; break; @@ -322,12 +321,12 @@ static void child_process() fprintf(CrashDump, Checkpoints[i]); fprintf(CrashDump, "\n"); - output_stack_trace( CrashDump, crash.BacktracePointers ); - fprintf(CrashDump, "\n"); - if( crash.type == CrashData::FORCE_CRASH_DEADLOCK ) + for( int i = 0; i < CrashData::MAX_BACKTRACE_THREADS; ++i ) { - fprintf(CrashDump, "Deadlocked with:\n"); - output_stack_trace( CrashDump, crash.BacktracePointers2 ); + if( !crash.BacktracePointers[i][0] ) + break; + fprintf( CrashDump, "Thread: %s\n", crash.m_ThreadName[i] ); + output_stack_trace( CrashDump, crash.BacktracePointers[i] ); fprintf(CrashDump, "\n"); } diff --git a/stepmania/src/archutils/Unix/CrashHandlerInternal.h b/stepmania/src/archutils/Unix/CrashHandlerInternal.h index ab5d57b808..f19525918b 100644 --- a/stepmania/src/archutils/Unix/CrashHandlerInternal.h +++ b/stepmania/src/archutils/Unix/CrashHandlerInternal.h @@ -2,7 +2,7 @@ #define CRASH_HANDLER_INTERNAL_H #include "Backtrace.h" -#define BACKTRACE_MAX_SIZE 1024 +#define BACKTRACE_MAX_SIZE 128 struct CrashData { @@ -12,17 +12,13 @@ struct CrashData SIGNAL, /* We're forcing a crash (eg. failed ASSERT). */ - FORCE_CRASH_THIS_THREAD, - - /* Deadlock detected; give a stack trace for two threads. */ - FORCE_CRASH_DEADLOCK + FORCE_CRASH, } type; /* Everything except FORCE_CRASH_THIS_THREAD: */ - const void *BacktracePointers[BACKTRACE_MAX_SIZE]; - - /* FORCE_CRASH_DEADLOCK only: */ - const void *BacktracePointers2[BACKTRACE_MAX_SIZE]; + enum { MAX_BACKTRACE_THREADS = 32 }; + const void *BacktracePointers[MAX_BACKTRACE_THREADS][BACKTRACE_MAX_SIZE]; + char m_ThreadName[MAX_BACKTRACE_THREADS][128]; /* SIGNAL only: */ int signal;