“This is the fourth day of my participation in the First Challenge 2022. For details: First Challenge 2022”

describe

Emulator and real machine debugging run fine, but export IPA package installation run crash. Make a note of it and remind others of the same problem to avoid detours.

Train of thought

First, keep your head clear when you encounter problems. Think about why this is happening.

  • Emulator and real debugging are running fine. Emulator and real debugging are inDeBugRun in mode
  • exportIpa packageThe environment isReleasemode

So you can focus on looking for crash information in Release mode to locate the problem.

View ipA packet crash logs

Connect the phone data line to the computer, use Xcode to look, Xcode -> Window -> Devices and Simulator

After entering, select [View Device Logs

Viewing Log Information

Log files look uncomfortable, there seems to be no way to locate specific problems, and then analyze

Dudeg/Relese/Relese/Relese/Relese/Relese/Relese

The default isDebugMode, selectReleaseMode, and then the local debugging and exported IPA environment is consistent.

Also check Zombie Ojects to locate wild Pointers and Zombie objects. Then run Xcode to locate the problem, and the console outputs the problem caused by the early release of the object being used.

Simply view the phone crash information several ways

Method 1: Set the phone to view crash logs

Steps: [Settings] -> [Privacy] -> [Analysis and Improvement] -> [Analysis data]

Mode 2: Xocde

The phone data line is connected to the computer, and you can look it by Xcode -> Window -> Devices and Simulator. The details are the same as above, please refer to the above example.

Method 3: The third software Itools

Connect iOS phone and computer through cable

Mode 4: Console resource library

You can see crash logs (.crash files) for all devices that have been synced with this computer.

Enter the file address below:

~/Library/Logs/CrashReporter/MobileDevice
Copy the code

Find your device’s logs

During the development of the program, the program crash can also occur, so the generated file directory is:

~/Library/Logs/DiagnosticReports/
Copy the code

Online crash log

Several ways to listen to crash online

Mode 1: SDK of third-party platform

For example: Tencent Bugly, Crashlytics, Umeng SDK

Method 2: Implement exception listening by yourself and submit it to the background

It is a bit more complicated to implement exception listening by itself, which requires asynchronous task listening and does not affect the task experience of the main process

A common cause of a crash

1. The array is out of bounds

App crashes when fetching index data out of bounds. There’s another case where adding nil to an array crashes

2. Multithreading

UI updates in child threads can crash. Multiple threads reading data may crash because of inconsistent processing timing, such as when one thread is emptying data while another thread is reading data.

3. The main thread does not respond

If the main thread does not respond after the specified time, it is killed by the Watchdog. At this point, the exception code corresponding to the crash problem is 0x8BADF00D.

4. Wild pointer

A wild pointer crash occurs when accessing a memory region that points to a deleted object. The wild pointer problem is something we need to pay attention to, because it is the most common condition that causes App crashes and one of the most difficult to locate

Signal capture Signal uncatched
KVO problem Background Task Timeout
The NSNotification thread is faulty Memory blow
An array The main thread is stuck beyond the threshold
Wild pointer .

Signals can be captured by crash log collection

Open the Xcode menu and choose Product -> Archive

Then, select “Upload your app’s symbols to receive symbolicated reports from Apple” and you will see the symbolized crash log in Xcode’s Archive.

However, this way of viewing logs is purely manual operation every time, and the timeliness is poor. As a result, most corporate crash log monitoring systems use third-party open source libraries such as PLCrashReporter to capture crash logs and upload them to their own servers for overall monitoring.

Companies that do not have server-side development capabilities, or are not sensitive to data, use Fabric or Bugly directly to monitor crashes.

Principle of signal acquisition

In crash logs, you’ll often see the following description:

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Copy the code

What it means is that the EXC_BAD_ACCESS exception will find the thread with the problem through the SIGSEGV signal. Although there are many types of signals, they can all be caught by registering signalHandler. The implementation code is as follows:

void registerSignalHandler(void) {
    signal(SIGSEGV, handleSignalException);
    signal(SIGFPE, handleSignalException);
    signal(SIGBUS, handleSignalException);
    signal(SIGPIPE, handleSignalException);
    signal(SIGHUP, handleSignalException);
    signal(SIGINT, handleSignalException);
    signal(SIGQUIT, handleSignalException);
    signal(SIGABRT, handleSignalException);
    signal(SIGILL, handleSignalException);
}
 
void handleSignalException(int signal) {
    NSMutableString *crashString = [[NSMutableString alloc]init];
    void* callstack[128];
    int i, frames = backtrace(callstack, 128);
    char** traceChar = backtrace_symbols(callstack, frames);
    for (i = 0; i <frames; ++i) {
        [crashString appendFormat:@"%s\n", traceChar[i]];
    }
    NSLog(crashString);
}
Copy the code

The above code registers all kinds of signals. After catching the exception signal, the current stack information can be obtained by using the backtrace_symbols method in handleSignalException. Stack information can be stored locally and then uploaded to the crash monitor server on the next startup.

Crash log collection with uncatable signals

When the App is back in the background, it is easy to crash even if the code logic is fine. Moreover, these crashes are often caused by the system forcibly killing some process, and signals thrown by the system forcibly killing cannot be captured due to system limitations.

5 ways to Keep the iOS background alive

  • Background Mode
  • Background Fetch
  • Silent Push
  • PushKit
  • Background Task (used by default after the App has stepped back)

Principles of acquisition Process

Background of Task, this way is the system provides beginBackgroundTaskWithExpirationHandler method to prolong the Background, you can solve your back behind still need some time to deal with some Task demands.

- (void)applicationDidEnterBackground:(UIApplication *)application { self.backgroundTaskIdentifier = [application BeginBackgroundTaskWithExpirationHandler: ^ (void) {/ / your task logic [self yourTask];}]; }Copy the code

In this code, yourTask will run for a maximum of 3 minutes, within 3 minutes yourTask will finish running and your App will hang. If yourTask doesn’t finish executing within 3 minutes, the system will force you to kill the process and crash, which is why apps tend to crash when they retire.

The Background of Task, we can according to beginBackgroundTaskWithExpirationHandler 3 minutes to keep alive the threshold makes the Background, first set a timer, when close to 3 minutes to determine whether a Background program in execution. If it is still being executed, we can judge that the program is about to crash in the background, and report and record it to achieve the effect of monitoring.

Crash log Analysis

The crash logs collected by us mainly include process information, basic information, exception information and thread backtracking.

  • Process information: Information about the crashed process, such as crash report unique identifier, unique key value, device identifier;
  • Basic information: date of crash, iOS version;
  • Exception information: exception type, exception code, exception thread;
  • Thread traceback: Method call stack at crash time.

Some of the cases that are killed by the system, we can analyze by exception coding. There are three common ones:

  • 0x8BADF00D indicates that the App does not respond within a certain period of time and is killed by the watchdog.
  • 0xdeadfa11: indicates that the App is forced to exit by a user.
  • 0xC00010FF: the App was killed because the device was running too hot.