review

To analyze iOS crashes, we need to master more knowledge. Next, I will introduce an analysis model,”Crash Log “, which can solve 80% of common crashes.

First, look at the description of application termination

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSInvocation getArgument:atIndex:]: index (0) out of bounds [-1, -1]'
Copy the code

“Application Specific Information” is a description of Application termination, from which we can know the Specific reason why the system killed the App and then quickly locate the problem code. Note that not all Crash logs have this description.

The second plate axe, check the exception type and exception code

Exception Type:  SIGSEGV
Exception Codes: SEGV_ACCERR at 0x110
Copy the code

“Exception Type” describes Unix Exception signals, as defined in the <sys/signal.h> file.

Our goal is to analyze iOS Crash by mastering five common exception types

Top1 SIGABRT signal

#define SIGABRT 6       /* abort() */
Copy the code

The lowest level of code triggered by this signal is abort(). The source could be either NSException or a Mach exception. NSException is an uncaught Objective-C exception that will eventually crash when converted to Unix’s SIGABRT signal

Ranked by SIGSEGV signal

#define SIGSEGV 11      /* segmentation violation */
Copy the code

SIGSEGV is a segment error, which means that the address corresponding to the accessed pointer is invalid (corresponding to SIGBUS). Generally, it can be summarized as three types of illegal memory access.

In the first case, if the value of the address is 0x1XXXXXXXX, which is a normal memory address, there is a high probability that the accessed memory address is released. Second, if the value of the address is 0x4 or 0x8 and other relatively small values, then the probability of accessing the memory address is null, which is usually caused by the assembly instruction to offset the address of the null pointer. Third, if the value of the address is 0x3A321129B9A9008e, which is a very long value, this relatively high probability is a wild pointer, the address has not been mapped from the system to the memory space of the current process. Wild Pointers are generally caused by multi-threaded manipulation of objects.

Top3 SIGTRAP

#define SIGTRAP 5       /* trace trap (not reset when caught) */
Copy the code

A TRAP is a TRAP. The first is triggered by trap methods provided by the compiler, such as ‘__builtin_trap()’. The second is that the Swift code runs abnormally and will eventually be converted to SIGTRAP. For example, assign nil to a non-optional type.

Apple SigTrap

Swift code will terminate with this exception type if an unexpected
condition is encountered at runtime such as:
a non-optional type with a nil value
a failed forced type conversion
Copy the code

Top4 SIGBUS

#define SIGBUS  10      /* bus error */ 
Copy the code

SIGBUS is a bus error, and the address corresponding to the access pointer is a valid address (corresponding to SIGSEGV). The possible cause is that the memory data is not aligned and the bus cannot use the pointer properly. Common OC code does not trigger, mainly due to system library methods or other C implementation methods.

Top5 SIGILL

#define SIGILL  4       /* illegal instruction (not reset when caught) */
Copy the code

SIGILL indicates that an invalid CPU instruction was executed. This can be caused by an attempt to execute a data segment, or by code that loops endlessly, causing a stack overflow.

IOS Mach exception, Unix signal exception and NSException exception

Third, check the thread call stack where Crash is located

Triggered by Thread: 17

Thread 17 Crashed:
0   libGPUSupportMercury.dylib      0x000000022d873fe4 _gpus_ReturnNotPermittedKillClient
1   AGXGLDriver                     0x0000000231f21ed8 0x0000000231efd000 + 151256
2   libGPUSupportMercury.dylib      0x000000022d874fac _gpusSubmitDataBuffers
Copy the code

“Triggered by Thread” describes the serial number of the Thread on which the Crash occurred. [Triggered by Thread] [Triggered by Thread] [Triggered by Thread] [Triggered by Thread] [Triggered by Thread] [Triggered by Thread] [Triggered by Thread] [Triggered by Thread] [Triggered by Thread] [Triggered by Thread] [Triggered by Thread] [Triggered by Thread] [Triggered by Thread] The call stack describes the stack frame, and each stack frame corresponds to a function (OC,C,C++). The last stack frame of Crash is numbered 0, and then the calling function of the upper layer is gradually traced back. It’s like being at a murder scene, where a forensic doctor dissects the victim, gradually retracing the changes in his body until he finds the fatal wound.

How is the thread call stack laid out?

Reference:

Note: iOS Mach, an abnormal Unix signals and NSException www.jianshu.com/p/04f822f92…

Note: How is the thread call stack laid out? Juejin. Cn/post / 689796…

The article summary

IOS internal power series

[iOS internal functions] Crash analysis model

In-depth analysis of the memory layout of Crash call stack

[iOS internal functions] ARM black magic – stack frame on and off the stack

Architecture series

What do architects often mean by “technical architecture”?

How to build APP stability system?

Series of thinking

The “Work Mindset Model” of high Performance Engineers