Make writing a habit together! This is the 12th day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

There are two common exceptions: Exception and Signal

  • When the triggerExceptionException, which can be successfully intercepted using the above method

The Signal exception is generated

  • When the triggerSignalAbnormal, by itselfNSSetUncaughtExceptionHandlerThe registration callback function is not intercepted, we need to targetSignalFor additional processing

In the analysis of Crash Signal:www.jianshu.com/p/3a9dc6bd5…

SignalThe callback function of

LGUncaughtExceptionHandler class, the increase of Signal processing

+ (void)installUncaughtExceptionHandler { NSSetUncaughtExceptionHandler(&LGExceptionHandlers); Signal (SIGABRT, LGSignalHandler); signal(SIGILL, LGSignalHandler); signal(SIGSEGV, LGSignalHandler); signal(SIGFPE, LGSignalHandler); signal(SIGBUS, LGSignalHandler); signal(SIGPIPE, LGSignalHandler); }Copy the code

To deal withSignalabnormal

Go to LGSignalHandler

Void LGSignalHandler(int signal) {int32_t exceptionCount = OSAtomicIncrement32(&LGUncaughtExceptionCount);  If (exceptionCount > LGUncaughtExceptionCount) {return; } NSString* description = nil; switch (signal) { case SIGABRT: description = [NSString stringWithFormat:@"Signal SIGABRT was raised!\n"]; break; case SIGILL: description = [NSString stringWithFormat:@"Signal SIGILL was raised!\n"]; break; case SIGSEGV: description = [NSString stringWithFormat:@"Signal SIGSEGV was raised!\n"]; break; case SIGFPE: description = [NSString stringWithFormat:@"Signal SIGFPE was raised!\n"]; break; case SIGBUS: description = [NSString stringWithFormat:@"Signal SIGBUS was raised!\n"]; break; case SIGPIPE: description = [NSString stringWithFormat:@"Signal SIGPIPE was raised!\n"]; break; default: description = [NSString stringWithFormat:@"Signal %d was raised!",signal]; } NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; NSArray *callStack = [LGUncaughtExceptionHandler backtrace]; [userInfo setObject:callStack forKey:LGUncaughtExceptionHandlerAddressesKey]; [userInfo setObject:[NSNumber numberWithInt:signal] forKey:LGUncaughtExceptionHandlerSignalKey]; NSException *ex = [NSException exceptionWithName:LGUncaughtExceptionHandlerSignalExceptionName reason:description userInfo:userInfo]; // In the main thread, Executes the specified method, WithObject method is to perform the incoming parameters [[[LGUncaughtExceptionHandler alloc] init] performSelectorOnMainThread:@selector(lg_handleException:) withObject:ex waitUntilDone:YES]; }Copy the code
  • willsignalPackaged together toNSMutableDictionaryIn the
  • Create a custom name and descriptionNSException
  • callLGUncaughtExceptionHandlerOf the classlg_handleExceptionObject methods

Enter the lg_handleException method, which contains Exception and Signa handling

- (void)lg_handleException:(NSException *)exception{ NSLog(@"%@", exception); UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Crash" message:nil preferredStyle:UIAlertControllerStyleAlert]; [controller addAction: [UIAlertAction actionWithTitle: @ "continue" style: UIAlertActionStyleDefault handler: ^ (UIAlertAction * _Nonnull action) { }]]; [controller addAction: [UIAlertAction actionWithTitle: @ "exit" style: UIAlertActionStyleCancel handler: ^ (UIAlertAction * _Nonnull action) { self.dismissed = YES; }]]; UIViewController *rootController = [UIApplication sharedApplication].keyWindow.rootViewController; [rootController presentViewController:controller animated:true completion:nil]; CFRunLoopRef runLoop = CFRunLoopGetCurrent(); CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop); while (! Self. Source) {// Click continue for (NSString *mode in (__bridge NSArray *)allModes) {// Quickly switch mode CFRunLoopRunInMode ((CFStringRef) mode, 0.001, false); }} // Click exit CFRelease(allModes); NSSetUncaughtExceptionHandler(NULL); signal(SIGABRT, SIG_DFL); signal(SIGILL, SIG_DFL); signal(SIGSEGV, SIG_DFL); signal(SIGFPE, SIG_DFL); signal(SIGBUS, SIG_DFL); signal(SIGPIPE, SIG_DFL); if ([[exception name] isEqual:LGUncaughtExceptionHandlerSignalExceptionName]) { kill(getpid(), [[[exception userInfo] objectForKey:LGUncaughtExceptionHandlerSignalKey] intValue]); } else { [exception raise]; }}Copy the code
  • SignaThe listener collects the corresponding memory
  • For the customNSExceptionSpecial treatment