Start dyLD dynamic library call libobJC dynamic library –> _objc_init (map_images (image file) + load_images(load method)) -main

  • Load – lazy_class(lazy_class without calling the load method)

First, collection method

1. Equipment collection

A. Use Xcode to obtain crash logs from the device

Connect your phone to Mac and select Xcode->Windows->Device and Simulator. Then click View Device Logs. You will see many Logs on your phone.

B. Obtain crash logs from the device

1) Go to Settings -> Privacy -> Analysis -> Analyze Data and find the log for the application you want. The log will be named in the following format: < app name > _ < crash time > _ < device name > 2) Select the desired log, copy the text or click the share button in the upper right corner to share it, and change the suffix of the shared.ips.synced or.txt file to.crash, Because Xcode does not accept crash logs without the.crash extension.

2. Apple dad sends crash report

Hexadecimal numbers

dSYM

The symbol set is a.dsym file that is generated every time we Archive a package and must be packaged using Xcode (Debug mode is turned off by default). We need to back up this file every time we release a version to facilitate future debugging. The symbol set stores the mapping table of file name, function name, line number and memory address. The Crash file can know exactly what Crash information is. If we do not use the.dsym file, the crash information will be incomplete (the official documentation says it will result in incomplete symbolization, i.e. some parts are symbolized and some are not). Each.dsym file has a UUID that corresponds to the UUID in the.app file, which represents an application, and each crash message in the.dsym file has a separate UUID that is used to check against the UUID of the application.Copy the code

Second, check

Before symbolizing a Crash file, you need to prepare.crash and.dsym and verify that they match

Why check:

Since the symbol set stores the information of file name, function name and line number, the symbol set will also change after compiling every code change, so in order to symbolize. Crash file,. Crash and symbol set must correspond one by one, that is to say, the 1.0 APP was generated by the 1.0 code, and the 1.0 symbol set was generated at the same time. A Bug occurred in the 1.0 APP and the crash file 104115 was generated. Only the symbol set of 1.0 can symbolize the crash file 104115. Meanwhile, the code of 1.0 must be found to accurately locate the place where the Bug was generated according to the symbolized crash file. How to tell if.crash,.dsym and.app (does it match your code) match? This is matched by a UUID, which is a unique identifier that Xcode automatically generates for each version at compile time. Even if an executable with the same functionality is rebuilt from the same source code using the same compiler Settings, it will have a different build UUID, and in short, a UNIQUE UUID. How do I obtain the UUID from the CLI? Obtain the UUID of. Crash

grep "'Your AppName' arm64" t.crash
Copy the code

Get the UUID of. DSYM

dwarfdump --uuid 'Your AppName'.app.dSYM
Copy the code

Get the UUID of. App

dwarfdump --uuid 'Your AppName'.app/'Your AppName'
Copy the code

3. Symbolic documents

Through the information stored in dSYM, the hexadecimal numbers in crash logs can be mapped into understandable file names, function names, and line numbers one by one. This process is called ** symbolization **Copy the code

1. Use XCode to automatically symbolize Crash files

Symbolicatecrash using the command line tool Symbolicatecrash

Four, analysis,

Crash types

1, EXC_BAD_ACCESS

Bad memory access

A crash caused by a wild pointer that accesses memory that has been freed. EXC_BAD_ACCESS appears when a message is sent to or sent to the freed object. The most common cause of EXC_BAD_ACCESS is the use of the wrong ownership modifier when initializing a variable in an initialization method, which causes the object to be released prematurely.Copy the code

Signal type that causes bad memory

  • SIGSEGV

    The object has been freed, the memory is invalid, the block memory address is not overwritten, so the memory is garbage, so the method call will cause SIGSEGV errorCopy the code
  • SIGBUS

    The memory address is not alignedCopy the code
  • SIGABRT

    Causes SIGABRT errors because there is no room in memory for thisCopy the code

Zombie object Resolution

Is an environment variable used to debug memory-related problems and track the release of objects. With NSZombieEnabled enabled, it will call your default dealloc implementation with a zombie implementation that will convert the object to a zombie when the reference count drops to zero. The purpose of a zombie object is that when you send a message to it, it displays a log and automatically jumps into the debuggerCopy the code

2, EXC_ARITHETIC

In addition to 0 operation

3, SIGILL

SIGILL stands for signal illegal Instruction. It occurs when an illegal instruction is executed on the processor. An invalid instruction is when a pointer to a function is given to another function that, for some reason, is broken and refers to a freed memory or data segment. Sometimes you get EXC_BAD_INSTRUCTION instead of SIGILL, which is the same thing, but EXC_* is equivalent to the signal being architecturally independent.Copy the code

4, SIGABRT

SIGABRT stands for SIGNAL ABORT. When the operating system detects an unsafe situation, it has more control over the situation; It can ask the process to clean up if necessary. There's no magic trick to debugging the underlying error that's causing this signal and basically saying there's no room in memory, okayCopy the code

5, SIGBUS

Memory not alignedCopy the code

5, the watchdog timed out

On iOS, it often happens when a synchronous network call blocks the main thread. Therefore, never make a synchronous network call.Copy the code

Mach exceptions and Signal signals

Blog.csdn.net/u013602835/…

If you want to listen for exceptions, you actually listen for Mach exceptions and Signal signals. Actually system has to provide us with a method to listener produce abnormalities, through NSSetUncaughtExceptionHandler (ginseng is a C function) method can directly capture exception information. However, this method does not catch signal due to memory access errors, so if we want to listen for most exceptions, we need to register signal(signal type, callback method) to catch the signal.

void InstallUncaughtExceptionHandler(void) {
    NSSetUncaughtExceptionHandler(&HandleException); // A systematic approach
    // Add the type of signal you want to listen on. When a signal of that type is sent, the SignalHandler method is called back
    signal(SIGABRT, SignalHandler);
    signal(SIGILL, SignalHandler);
    signal(SIGSEGV, SignalHandler);
    signal(SIGFPE, SignalHandler);
    signal(SIGBUS, SignalHandler);
    signal(SIGPIPE, SignalHandler);
Copy the code