From 0b34216843c4b434c45287475b1f0953bf8c56b8 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Fri, 19 Mar 2004 08:17:44 +0000 Subject: [PATCH] OS X crash handling cleanup --- .../src/arch/ArchHooks/ArchHooks_darwin.cpp | 2 +- stepmania/src/archutils/Darwin/Crash.cpp | 15 ---- stepmania/src/archutils/Darwin/Crash.h | 4 - stepmania/src/archutils/Unix/Backtrace.cpp | 12 ++- stepmania/src/archutils/Unix/Backtrace.h | 12 +++ stepmania/src/archutils/Unix/CrashHandler.cpp | 73 ++++++++++++------- stepmania/src/archutils/Unix/CrashHandler.h | 4 + .../src/archutils/Unix/CrashHandlerChild.cpp | 6 ++ .../src/archutils/Unix/CrashHandlerInternal.h | 9 ++- 9 files changed, 87 insertions(+), 50 deletions(-) diff --git a/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp b/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp index 3ff58aa5c6..e936cc886f 100644 --- a/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp +++ b/stepmania/src/arch/ArchHooks/ArchHooks_darwin.cpp @@ -57,7 +57,7 @@ ArchHooks_darwin::ArchHooks_darwin() MessageBoxOK(error, ""); exit(0); } - InstallExceptionHandler(HandleException); + InstallExceptionHandler( CrashExceptionHandler ); } #define CASE_GESTALT_M(str,code,result) case gestalt##code: str = result; break diff --git a/stepmania/src/archutils/Darwin/Crash.cpp b/stepmania/src/archutils/Darwin/Crash.cpp index bb2dc11bab..2b1869a99c 100644 --- a/stepmania/src/archutils/Darwin/Crash.cpp +++ b/stepmania/src/archutils/Darwin/Crash.cpp @@ -15,21 +15,6 @@ #include #include -static void *crashedFramePtr = NULL; - -OSStatus HandleException(ExceptionInformation *theException) -{ - crashedFramePtr = (void *)theException->registerImage->R1.lo; - CrashSignalHandler(theException->theKind); - return -1; -} - - -void *GetCrashedFramePtr() -{ - return (crashedFramePtr ? crashedFramePtr : __builtin_return_address(2)); -} - void InformUserOfCrash( const CString &sPath ) { CFStringRef error = CFStringCreateWithCString(NULL, diff --git a/stepmania/src/archutils/Darwin/Crash.h b/stepmania/src/archutils/Darwin/Crash.h index 36ef3a4a55..88f7cac059 100644 --- a/stepmania/src/archutils/Darwin/Crash.h +++ b/stepmania/src/archutils/Darwin/Crash.h @@ -9,10 +9,6 @@ * */ -#include - -OSStatus HandleException(ExceptionInformation *theException); -void *GetCrashedFramePtr(); void InformUserOfCrash( const CString &sPath ); #endif /* DARWIN_CRASH_H */ diff --git a/stepmania/src/archutils/Unix/Backtrace.cpp b/stepmania/src/archutils/Unix/Backtrace.cpp index 07bc13b211..3549bee6a4 100644 --- a/stepmania/src/archutils/Unix/Backtrace.cpp +++ b/stepmania/src/archutils/Unix/Backtrace.cpp @@ -290,11 +290,21 @@ typedef struct Frame void *linkReg; } *FramePtr; +void GetExceptionBacktraceContext( BacktraceContext *ctx, ExceptionInformation *exception ) +{ + ctx->FramePtr = (void *) theException->registerImage->R1.lo; +} + +void GetCurrentBacktraceContext( BacktraceContext *ctx ) +{ + ctx->FramePtr = __builtin_return_address(2); +} + void InitializeBacktrace() { } void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) { - Frame *frame = (Frame *) GetCrashedFramePtr(); + Frame *frame = (Frame *) ctx->FramePtr; unsigned i = 0; while( frame && i < size-1 ) // -1 for NULL diff --git a/stepmania/src/archutils/Unix/Backtrace.h b/stepmania/src/archutils/Unix/Backtrace.h index 1144255fe7..db9a0ed168 100644 --- a/stepmania/src/archutils/Unix/Backtrace.h +++ b/stepmania/src/archutils/Unix/Backtrace.h @@ -10,6 +10,10 @@ struct BacktraceContext long eip, esp, ebp; pid_t pid; #endif + +#if defined(DARWIN) + void *FramePtr; +#endif }; /* Initialize. This is optional. If not called explicitly, it will be @@ -33,6 +37,14 @@ void GetCurrentBacktraceContext( BacktraceContext *ctx ); #include void GetSignalBacktraceContext( BacktraceContext *ctx, const ucontext_t *uc ); +#if defined(DARWIN) +#include + +/* Set up a BacktraceContext to get a backtrace after receiving an exception, given + * an ExceptionInformation*. */ +void GetExceptionBacktraceContext( BacktraceContext *ctx, ExceptionInformation *exception ); +#endif + #define BACKTRACE_METHOD_NOT_AVAILABLE ((void*) -1) #endif diff --git a/stepmania/src/archutils/Unix/CrashHandler.cpp b/stepmania/src/archutils/Unix/CrashHandler.cpp index 9237f548f0..2f88ac1782 100644 --- a/stepmania/src/archutils/Unix/CrashHandler.cpp +++ b/stepmania/src/archutils/Unix/CrashHandler.cpp @@ -169,35 +169,9 @@ static const char *itoa(unsigned n) return p; } -const char *SignalName( int signo ) +#if defined(DARWIN) +const char *ExceptionName( int signo ) { -#if !defined(DARWIN) -#define X(a) case a: return #a; - switch( signo ) - { - case SIGALRM: return "Alarm"; - case SIGBUS: return "Bus error"; - case SIGFPE: return "Floating point exception"; - X(SIGHUP) - case SIGILL: return "Illegal instruction"; - X(SIGINT) - case SIGPIPE: return "Broken pipe"; - case SIGABRT: return "Aborted"; - X(SIGQUIT) - case SIGSEGV: return "Segmentation fault"; - X(SIGTRAP) X(SIGTERM) X(SIGVTALRM) X(SIGXCPU) X(SIGXFSZ) -#if defined(HAVE_DECL_SIGPWR) && HAVE_DECL_SIGPWR - X(SIGPWR) -#endif - default: - { - static char buf[128]; - strcpy( buf, "Unknown signal " ); - strcat( buf, itoa(signo) ); - return buf; - } - } -#else #define X(code) case k##code: return #code; switch( signo ) { @@ -223,7 +197,38 @@ const char *SignalName( int signo ) return buf; } } +#undef X +} #endif + +const char *SignalName( int signo ) +{ +#define X(a) case a: return #a; + switch( signo ) + { + case SIGALRM: return "Alarm"; + case SIGBUS: return "Bus error"; + case SIGFPE: return "Floating point exception"; + X(SIGHUP) + case SIGILL: return "Illegal instruction"; + X(SIGINT) + case SIGPIPE: return "Broken pipe"; + case SIGABRT: return "Aborted"; + X(SIGQUIT) + case SIGSEGV: return "Segmentation fault"; + X(SIGTRAP) X(SIGTERM) X(SIGVTALRM) X(SIGXCPU) X(SIGXFSZ) +#if defined(HAVE_DECL_SIGPWR) && HAVE_DECL_SIGPWR + X(SIGPWR) +#endif + default: + { + static char buf[128]; + strcpy( buf, "Unknown signal " ); + strcat( buf, itoa(signo) ); + return buf; + } + } +#undef X } const char *SignalCodeName( int signo, int code ) @@ -423,6 +428,18 @@ void CrashSignalHandler( int signal, siginfo_t *si, const ucontext_t *uc ) RunCrashHandler( &crash ); } +#if defined(DARWIN) +OSStatus CrashExceptionHandler( ExceptionInformation *e ) +{ + CrashData crash; + crash.type = CrashData::OSX_EXCEPTION; + crash.kind = theException->theKind; + + GetExceptionBacktraceContext( &crash.ctx, e ); + RunCrashHandler( &crash ); + return -1; +} +#endif void InitializeCrashHandler() { diff --git a/stepmania/src/archutils/Unix/CrashHandler.h b/stepmania/src/archutils/Unix/CrashHandler.h index cafe1b07b5..994cf530f5 100644 --- a/stepmania/src/archutils/Unix/CrashHandler.h +++ b/stepmania/src/archutils/Unix/CrashHandler.h @@ -8,5 +8,9 @@ void CrashSignalHandler( int signal, siginfo_t *si, const ucontext_t *uc ); void CrashHandlerHandleArgs( int argc, char* argv[] ); void InitializeCrashHandler(); +#if defined(DARWIN) +OSStatus CrashExceptionHandler( ExceptionInformation *e ); +#endif + #endif diff --git a/stepmania/src/archutils/Unix/CrashHandlerChild.cpp b/stepmania/src/archutils/Unix/CrashHandlerChild.cpp index 4de02b2c56..8581f25b9b 100644 --- a/stepmania/src/archutils/Unix/CrashHandlerChild.cpp +++ b/stepmania/src/archutils/Unix/CrashHandlerChild.cpp @@ -161,6 +161,12 @@ static void child_process() break; } +#if defined(DARWIN) + case CrashData::OSX_EXCEPTION: + reason = ExceptionName( crash.kind ); + break; +#endif + case CrashData::FORCE_CRASH_THIS_THREAD: crash.reason[ sizeof(crash.reason)-1] = 0; reason = crash.reason; diff --git a/stepmania/src/archutils/Unix/CrashHandlerInternal.h b/stepmania/src/archutils/Unix/CrashHandlerInternal.h index 39ec2f809c..52821fc103 100644 --- a/stepmania/src/archutils/Unix/CrashHandlerInternal.h +++ b/stepmania/src/archutils/Unix/CrashHandlerInternal.h @@ -11,7 +11,7 @@ struct CrashData SIGNAL, #if defined(DARWIN) - /* We received a fatal exception. si and uc are valid. */ + /* We received a fatal exception. */ OSX_EXCEPTION, #endif @@ -31,6 +31,9 @@ struct CrashData int signal; siginfo_t si; + /* OSX_EXCEPTION only: */ + int kind; + /* FORCE_CRASH_THIS_THREAD only: */ char reason[256]; }; @@ -41,5 +44,9 @@ struct CrashData const char *SignalName( int signo ); const char *SignalCodeName( int signo, int code ); +#if defined(DARWIN) +const char *ExceptionName( int signo ); +#endif + #endif