OS X crash handling cleanup
This commit is contained in:
@@ -57,7 +57,7 @@ ArchHooks_darwin::ArchHooks_darwin()
|
|||||||
MessageBoxOK(error, "");
|
MessageBoxOK(error, "");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
InstallExceptionHandler(HandleException);
|
InstallExceptionHandler( CrashExceptionHandler );
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CASE_GESTALT_M(str,code,result) case gestalt##code: str = result; break
|
#define CASE_GESTALT_M(str,code,result) case gestalt##code: str = result; break
|
||||||
|
|||||||
@@ -15,21 +15,6 @@
|
|||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
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 )
|
void InformUserOfCrash( const CString &sPath )
|
||||||
{
|
{
|
||||||
CFStringRef error = CFStringCreateWithCString(NULL,
|
CFStringRef error = CFStringCreateWithCString(NULL,
|
||||||
|
|||||||
@@ -9,10 +9,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <MachineExceptions.h>
|
|
||||||
|
|
||||||
OSStatus HandleException(ExceptionInformation *theException);
|
|
||||||
void *GetCrashedFramePtr();
|
|
||||||
void InformUserOfCrash( const CString &sPath );
|
void InformUserOfCrash( const CString &sPath );
|
||||||
|
|
||||||
#endif /* DARWIN_CRASH_H */
|
#endif /* DARWIN_CRASH_H */
|
||||||
|
|||||||
@@ -290,11 +290,21 @@ typedef struct Frame
|
|||||||
void *linkReg;
|
void *linkReg;
|
||||||
} *FramePtr;
|
} *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 InitializeBacktrace() { }
|
||||||
|
|
||||||
void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx )
|
void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx )
|
||||||
{
|
{
|
||||||
Frame *frame = (Frame *) GetCrashedFramePtr();
|
Frame *frame = (Frame *) ctx->FramePtr;
|
||||||
|
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
while( frame && i < size-1 ) // -1 for NULL
|
while( frame && i < size-1 ) // -1 for NULL
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ struct BacktraceContext
|
|||||||
long eip, esp, ebp;
|
long eip, esp, ebp;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(DARWIN)
|
||||||
|
void *FramePtr;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Initialize. This is optional. If not called explicitly, it will be
|
/* Initialize. This is optional. If not called explicitly, it will be
|
||||||
@@ -33,6 +37,14 @@ void GetCurrentBacktraceContext( BacktraceContext *ctx );
|
|||||||
#include <ucontext.h>
|
#include <ucontext.h>
|
||||||
void GetSignalBacktraceContext( BacktraceContext *ctx, const ucontext_t *uc );
|
void GetSignalBacktraceContext( BacktraceContext *ctx, const ucontext_t *uc );
|
||||||
|
|
||||||
|
#if defined(DARWIN)
|
||||||
|
#include <MachineExceptions.h>
|
||||||
|
|
||||||
|
/* 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)
|
#define BACKTRACE_METHOD_NOT_AVAILABLE ((void*) -1)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -169,35 +169,9 @@ static const char *itoa(unsigned n)
|
|||||||
return p;
|
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;
|
#define X(code) case k##code: return #code;
|
||||||
switch( signo )
|
switch( signo )
|
||||||
{
|
{
|
||||||
@@ -223,7 +197,38 @@ const char *SignalName( int signo )
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#undef X
|
||||||
|
}
|
||||||
#endif
|
#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 )
|
const char *SignalCodeName( int signo, int code )
|
||||||
@@ -423,6 +428,18 @@ void CrashSignalHandler( int signal, siginfo_t *si, const ucontext_t *uc )
|
|||||||
RunCrashHandler( &crash );
|
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()
|
void InitializeCrashHandler()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,5 +8,9 @@ void CrashSignalHandler( int signal, siginfo_t *si, const ucontext_t *uc );
|
|||||||
void CrashHandlerHandleArgs( int argc, char* argv[] );
|
void CrashHandlerHandleArgs( int argc, char* argv[] );
|
||||||
void InitializeCrashHandler();
|
void InitializeCrashHandler();
|
||||||
|
|
||||||
|
#if defined(DARWIN)
|
||||||
|
OSStatus CrashExceptionHandler( ExceptionInformation *e );
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,12 @@ static void child_process()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(DARWIN)
|
||||||
|
case CrashData::OSX_EXCEPTION:
|
||||||
|
reason = ExceptionName( crash.kind );
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case CrashData::FORCE_CRASH_THIS_THREAD:
|
case CrashData::FORCE_CRASH_THIS_THREAD:
|
||||||
crash.reason[ sizeof(crash.reason)-1] = 0;
|
crash.reason[ sizeof(crash.reason)-1] = 0;
|
||||||
reason = crash.reason;
|
reason = crash.reason;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ struct CrashData
|
|||||||
SIGNAL,
|
SIGNAL,
|
||||||
|
|
||||||
#if defined(DARWIN)
|
#if defined(DARWIN)
|
||||||
/* We received a fatal exception. si and uc are valid. */
|
/* We received a fatal exception. */
|
||||||
OSX_EXCEPTION,
|
OSX_EXCEPTION,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -31,6 +31,9 @@ struct CrashData
|
|||||||
int signal;
|
int signal;
|
||||||
siginfo_t si;
|
siginfo_t si;
|
||||||
|
|
||||||
|
/* OSX_EXCEPTION only: */
|
||||||
|
int kind;
|
||||||
|
|
||||||
/* FORCE_CRASH_THIS_THREAD only: */
|
/* FORCE_CRASH_THIS_THREAD only: */
|
||||||
char reason[256];
|
char reason[256];
|
||||||
};
|
};
|
||||||
@@ -41,5 +44,9 @@ struct CrashData
|
|||||||
const char *SignalName( int signo );
|
const char *SignalName( int signo );
|
||||||
const char *SignalCodeName( int signo, int code );
|
const char *SignalCodeName( int signo, int code );
|
||||||
|
|
||||||
|
#if defined(DARWIN)
|
||||||
|
const char *ExceptionName( int signo );
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user