I am integrating the Firebase Crashlytics crash reporting framework into my iOS application. The application is written in ObjC and already has custom signal handlers so there comes the issue that I observe - if the application custom handlers are initialized after Firebase Crashlytics custom handlers - they do not fire, but Crashlytics handlers get fired. On the other hand, if my application handlers are registered first then all works as expected.
I inspected the Firebase Crashlytics code trying to find what might be reason why any later signals are not being fired but couldn't catch anything interesting.
Here's the code where signal is triggered by pressing the UI button. In fact I see the crash reported in Firebase Dashboard, but I don't see a file created by handler_1 nor I see the NSLog message.
#import "ViewController.h"
#import <signal.h>
@import Firebase;
@interface ViewController ()
@end
@implementation ViewController
static const int signals[] = {SIGSEGV, SIGFPE, SIGTRAP, SIGILL, SIGABRT, SIGPIPE, SIGBUS};
#define MAXSIG 14
struct sigaction handler_prev_1[MAXSIG];
void handler_1(int sig, siginfo_t* info, void* p) {
NSString *someText = @"Random Text To Be Saved";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *fileName = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"signal_handler.txt"];
[someText writeToFile:fileName atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@"Hello there!");
}
void register_handlers_1() {
struct sigaction sa = {};
sa.sa_sigaction = handler_1;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_SIGINFO;
for (int i = 0; i < sizeof(signals)/sizeof(signals[0]); i++)
{
int res = sigaction(signals[i], &sa, &handler_prev_1[signals[i]]);
NSLog(@"Registering signal %d handler = %d", signals[i], res);
}
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// If I don't call this then the handler_1 is fired well
[FIRApp configure];
// Crashlytics is running a deffered signals check in (crashReportingSetupCompleted) after two seconds as I understand from their code,
// so I am trying to avoid any unwanted interference with this 3 seconds sleep.
[NSThread sleepForTimeInterval:3.000];
register_handlers_1();
UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(20, 50, 100, 30);
[button setTitle:@"Crash" forState:UIControlStateNormal];
[button addTarget:self action:@selector(crashButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (IBAction)crashButtonTapped:(id)sender {
*(volatile int*)0 = 0;
}