Skip to content

Commit

Permalink
Merge pull request #802 from mixpanel/fix-signal-handler
Browse files Browse the repository at this point in the history
Fix signal handler
  • Loading branch information
zihejia authored Oct 10, 2018
2 parents 0ca59de + 3c99e92 commit f9e78d8
Showing 1 changed file with 13 additions and 9 deletions.
22 changes: 13 additions & 9 deletions Mixpanel/MixpanelExceptionHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#import "MixpanelPrivate.h"
#import "MPLogger.h"
#include <libkern/OSAtomic.h>
#include <execinfo.h>

static NSString * const UncaughtExceptionHandlerSignalExceptionName = @"UncaughtExceptionHandlerSignalExceptionName";
static NSString * const UncaughtExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey";
Expand Down Expand Up @@ -43,7 +42,6 @@ - (instancetype)init {
if (self) {
// Create a hash table of weak pointers to mixpanel instances
_mixpanelInstances = [NSHashTable weakObjectsHashTable];

_prev_signal_handlers = calloc(NSIG, sizeof(struct sigaction));

// Install our handler
Expand All @@ -64,7 +62,7 @@ - (void)setupHandlers {
sigemptyset(&action.sa_mask);
action.sa_flags = SA_SIGINFO;
action.sa_sigaction = &MPSignalHandler;
int signals[] = {SIGABRT, SIGILL, SIGSEGV, SIGFPE, SIGBUS, SIGPIPE};
int signals[] = {SIGABRT, SIGILL, SIGSEGV, SIGFPE, SIGBUS};
for (int i = 0; i < sizeof(signals) / sizeof(int); i++) {
struct sigaction prev_action;
int err = sigaction(signals[i], &action, &prev_action);
Expand All @@ -82,26 +80,32 @@ - (void)addMixpanelInstance:(Mixpanel *)instance {
[self.mixpanelInstances addObject:instance];
}

void MPSignalHandler(int signal, struct __siginfo *info, void *context) {
void MPSignalHandler(int signalNumber, struct __siginfo *info, void *context) {
MixpanelExceptionHandler *handler = [MixpanelExceptionHandler sharedHandler];

int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount <= UncaughtExceptionMaximum) {
NSDictionary *userInfo = @{UncaughtExceptionHandlerSignalKey: @(signal)};
NSDictionary *userInfo = @{UncaughtExceptionHandlerSignalKey: @(signalNumber)};
NSException *exception = [NSException exceptionWithName:UncaughtExceptionHandlerSignalExceptionName
reason:[NSString stringWithFormat:@"Signal %d was raised.", signal]
reason:[NSString stringWithFormat:@"Signal %d was raised.", signalNumber]
userInfo:userInfo];

[handler mp_handleUncaughtException:exception];
}

struct sigaction prev_action = handler.prev_signal_handlers[signal];
struct sigaction prev_action = handler.prev_signal_handlers[signalNumber];
// Since there is no way to pass through to the default handler, re-raise the signal as our best efforts
if (prev_action.sa_handler == SIG_DFL) {
signal(signalNumber, SIG_DFL);
raise(signalNumber);
return;
}
if (prev_action.sa_flags & SA_SIGINFO) {
if (prev_action.sa_sigaction) {
prev_action.sa_sigaction(signal, info, context);
prev_action.sa_sigaction(signalNumber, info, context);
}
} else if (prev_action.sa_handler) {
prev_action.sa_handler(signal);
prev_action.sa_handler(signalNumber);
}
}

Expand Down

0 comments on commit f9e78d8

Please # to comment.