Preface
Although people do not want to see the program crashes, but may crash is the reality of every application must face, since the collapse has occurred, can not stop, then we let it collapse also a point of light.
The IOS SDK provides an out-of-the-box function Nssetuncaughtexceptionhandler for exception handling, but with very limited functionality, most of the causes of crashes such as memory access errors, repeated releases, and so on.
Because of this error it throws signal, so it has to be done specifically for signal processing.
What is signal
In computer science, signaling ( English:signals) is a restrictive way of interprocess communication in Unix, Unix-like, and other POSIX-compliant operating systems. It is an asynchronous notification mechanism used to alert a process that an event has occurred. When a signal is sent to a process, the operating system interrupts the normal process of control, at which point any non-atomic operations are interrupted. If a process defines a handler for a signal, it is executed, otherwise the default handler function is executed.
How to use signal
In Project engineering, when you want to use Signal , you can use it by introducing signal.h :
#include <sys/signal.h>
A large number of system signal identifiers are defined within the sys/signal file
Use these signal identifiers to pass the function void (*signal (int, void (*) (int)))) (int); To use it as follows:
Defines a callback function that receives a signal void handleexception (int signo) { printf ("Lanou's sig is:%d", Signo);} Registers the callback function of the alerm signal signal (SIGALRM, handleexception);
The signal processing function can be set by the signal () system. If the corresponding processing function is not set for a signal, the default handler is used, otherwise the signal is intercepted by the process and the corresponding handler function is called. In the absence of a handler function, the program can specify two behaviors: Ignore the signal sig_ign or use the default handler function SIG_DFL . However, there are two signals that cannot be intercepted and processed: SIGKILL, SIGSTOP .
types of signal signals
- sigabrt--Program abort Command abort signal
- sigalrm--Program Timeout signal
- sigfpe--program floating point anomaly signal
- sigill--Program Illegal Command signal
- sighup--Program Terminal Stop signal
- sigint--Program Keyboard Interrupt Signal
- sigkill--program end receive abort signal
- sigterm--Program Kill stop Signal
- sigstop--Program Keyboard Abort signal
- sigsegv--Program Invalid memory abort signal
- sigbus--Program Memory byte misaligned abort signal
- sigpipe--program socket send failed abort signal
how signal signals are used in iOS development
Create a Signalhandler static class
signalhandler.h// racsample//// Created by Lewis on 4/29/15.// Copyright (c), Lewis. All rights reserved.//#import <Foundation/Foundation.h> #include <sys/signal.h> @interface Signalhandler: nsobject//registration method of capturing signals + (void) Registersignalhandler; @end
In this static class, we introduce the sys/signal.h
And added a static method + (void) Registersignalhandler; used to register a signal notification message.
signalhandler.mm
signalhandler.m//racsample////Created by Lewis on 4/29/15.//Copyright (c), Lewis. All rights reserved.//#import "SignalHandler.h" #import <UIKit/UIKit.h> #include <libkern/osatomic.h># Include <execinfo.h>//the number of exceptions currently handled volatile int32_t Uncaughtexceptioncount = 0;//The maximum number of exceptions that can be handled volatile int32_t Uncaughtexceptionmaximum = 10;//callback function after capturing signal void handleexception (int signo) {int32_t Exceptioncount = OSAtomicIncrement3 2 (&uncaughtexceptioncount); if (Exceptioncount > Uncaughtexceptionmaximum) {return; } nsmutabledictionary *userinfo =[nsmutabledictionary dictionarywithobject:[nsnumber NumberWithInt:signo] forKey:@ " Signal "]; Create an OC exception object nsexception *ex = [nsexception exceptionwithname:@ "Signalexceptionname" reason:[nsstring stringwithformat:@ "Signal%d was raised.\n", Signo] userinfo:userinfo]; Handling exception messages [[Signalhandler Instance] Performselectoronmainthread: @selector (handleexception:) Withobject:ex Waituntildone:yes];} @impLementation signalhandlerstatic Signalhandler *s_signalhandler = nil;+ (instancetype) Instance{static dispatch_on ce_t Oncetoken; Dispatch_once (&oncetoken, ^{if (S_signalhandler = = nil) {S_signalhandler = [[Signalhandler alloc ] init]; } }); return S_signalhandler;} + (void) registersignalhandler{//Registry program abort signal due to abort () function call signal (SIGABRT, handleexception); Registration procedures due to illegal instructions produced by the program Stop Signal signal (Sigill, handleexception); Program Abort signal signal (SIGSEGV, handleexception) due to invalid memory reference in registry program; Program Abort signal signal (SIGFPE, handleexception) due to abnormal floating-point number in registration program; Program Abort signal signal (Sigbus, handleexception) due to non-alignment of memory address by registry program; Program Abort signal signal (Sigpipe, handleexception) due to failure to send message via port BOOL isdismissed = no;//method used to handle exceptions-(void) HandleException: (NSException *) exception{cfrunloopref runloop = cfrunloopgetc Urrent (); Cfarrayref allmodes = Cfrunloopcopyallmodes (Runloop); Uialertview *alertview = [[Uialertview alloc] Initwithtitle:@ "program problem" message:@ "Crash Information" Delegate:self cancelbuttontitle:@ "Cancel" otherbuttontitles:nil]; [Alertview show]; [Alertview Release],alertview = nil; When receiving an exception handling message, let the program start Runloop to prevent the program from dying while (!isdismissed) {for (NSString *mode in (Nsarray *) allmodes) { Cfrunloopruninmode ((cfstringref) mode, 0.001, false); }}//When clicking the Cancel button of the popup view Oh, isdimissed = yes, the top loop jumps out of 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);} -(void) Alertview: (Uialertview *) Analertview Clickedbuttonatindex: (nsinteger) anindex{//Because this pop-up view has only one Cancel button, So make a direct modification isdimsmissed this variable isdismissed = YES;} @end
In. mm files, the following methods are used altogether:
• handleexception used as a callback function for the signal function;
• Instance used to obtain a singleton object of the Signalhandler class;
• The public method Registersignalhandler declared in the SignalHandler.h header file;
• -(void) HandleException: (NSException *) exption used as the custom method for handling exceptions in OC
• -(void) Alertview: (Uialertview *) Analertview Clickedbuttonatindex: (nsinteger) Anindex The proxy object to use as the popup view
Then through this article, you should be able to calmly deal with the iOS crash message.
[IOS] use signal to allow apps to crash gracefully