我正在将 Firebase Crashlytics 崩溃报告框架集成到我的 iOS 应用程序中。该应用程序是用 ObjC 编写的,并且已经具有自定义信号处理程序,因此出现了我观察到的问题 - 如果应用程序自定义处理程序在 Firebase Crashlytics 自定义处理程序之后初始化 - 它们不会触发,但 Crashlytics 处理程序会被触发。另一方面,如果我的应用程序处理程序首先注册,那么一切都按预期工作。
我检查了 Firebase Crashlytics 代码,试图找出任何后来的信号没有被触发但无法捕捉到任何有趣的东西的原因。
这是通过按下 UI 按钮触发信号的代码。事实上,我在 Firebase 仪表板中看到了崩溃报告,但我没有看到 handler_1 创建的文件,也没有看到 NSLog 消息。
#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;
}