背景:项目中有个SDK库(Golang),会抛出异常信号,第三方crash日志记录工具会分析这个信号而造成崩溃,我们做作的就是在三方注册异常监听后,重新注册,覆盖监听,达到避免crash的目的。
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface TestCrash : NSObject
+(void)registerExceptionHandler;
@end
NS_ASSUME_NONNULL_END
#import "TestCrash.h"
#include <execinfo.h>
@implementation TestCrash
+(void)registerExceptionHandler
{
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGTRAP, SignalHandler);
signal(SIGPIPE, SignalHandler);
signal(SIGSEGV, SignalHandler);
}
void SignalHandler(int signalCode)
{
const NSInteger kCSIIStackFramesMax = 128;
void *stack[kCSIIStackFramesMax];
NSInteger frameCount = backtrace(stack, kCSIIStackFramesMax);
char **lines = backtrace_symbols(stack, (int)frameCount);
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frameCount];
for (NSInteger i = 1; i < frameCount; i++)
[backtrace addObject:[NSString stringWithUTF8String:lines[i]]];
free(lines);
NSDictionary *userInfo = @{@"signal_code": @(signalCode), @"kCSIIExceptionUserInfoBacktraceKey": backtrace};
NSString *reason = [NSString stringWithFormat:@"App terminated by SIG%@", [NSString stringWithUTF8String:sys_signame[signalCode]].uppercaseString];
NSException *e = [NSException exceptionWithName:@"Fatal Signal" reason:reason userInfo:userInfo];
NSLog(@"=======>%@",userInfo);
sleep(2.0);
}
@end
最好能用signal(SIGBUS, SIG_IGN);
这种形式,让系统忽略处理
网友评论