“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 in
DeBug
Run in mode - export
Ipa package
The environment isRelease
mode
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 isDebug
Mode, selectRelease
Mode, 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.