Developer on Alibaba Coud: Build your first app with APIs, SDKs, and tutorials on the Alibaba Cloud. Read more ＞
As an application developer, have you ever experienced the following? To ensure that your application is correct, you must perform a lot of testing before submitting it to the app store. It runs well on your device, but some users complain that it will crash after they go to the app store! If you are a perfectionist like me, you certainly want to perfect your applications. So you open the code to fix the crash ...... But where should I start? At this time, the IOS Crash log comes in handy. In most cases, you can learn detailed and useful information about flashback. In this tutorial, you will learn some common crash log cases and how to obtain crash log files from the development device and iTunes connect. You will also learn symbolication, from log tracing to code. You will also learn how to debug an application that will crash in the future. Let's get started!
What is a crash log? Where can I get it?When applications on iOS devices crash, the operating system generates a crash report, also called a crash log, and stores it on the device. There is a lot of useful information on the crash log, including when the application is crashed. Generally, there is a complete stack trace information for each thread being executed, so you can find out what each thread is doing when a crash occurs, and identify the thread on which the crash occurs. There are several methods to obtain the crash log from the device. After the device is synchronized with the iTunes store on the computer, the crash logs are saved on the computer. Depending on the computer operating system, the crash log will be saved in the following locations: Mac OS X :~ /Library/logs/crashreporter/mobiledevice/Windows XP: C: Documents and Settings <username> application dataapple computerlogscrashreportermobiledevice <device_name> Windows Vista or 7: C: users <username> appdataroamingapple computerlogscrashreportermobiledevice <device_name> when a user complains about the crash, you can ask him to synchronize the device with iTunes and, depending on the operating system, download the crash log from the above location and send it to you by email. You must obtain all crash logs generated by your device whenever possible. The more crash logs, the easier it is to diagnose the problem! In addition, if you have installed xcode, you can easily obtain crash logs from your device through xcode. Connect the iOS device to your computer and then open xcode. Select window from the menu bar, and then select organizer
(Shortcut is Shift-CMD-2). On the organizer window, select the devices tab. On the left-side Navigation Pane, select
Device logs, as shown in: Check that there are several device logs menu items on the left. The device logs under the library is the log of all your devices (once connected to xcode. The device logs under each device is the log of the corresponding device. After the application is submitted to the App Store, you can also obtain the user's crash log from iTunes connect. log on to iTunes connect and select
Manage your applications, click the corresponding application, click View Details under the application icon, and then click crash reports in the Links section on the right.
. If no crash log exists, Click Refresh to refresh it. If your applications are not sold much, or your iTunes connect account may not have any crash logs. If there is a crash log on iTunes connect, you will see: Sometimes, even if there is a user report crash, you still cannot see the crash report. In this case, we recommend that you directly send the crash report to you.
Under what circumstances will crash logs be generated?Two major scenarios will generate crash logs:
1. The application violates operating system rules.2. There are bugs in the application.Violation of IOS rules includes watchdog timeout during startup, recovery, suspension, and exit, user forced exit, and low memory termination. Let's take a closer look.
Watchdog timeout MechanismStarting from IOS 4.x, when you exit the application, the application will not be terminated immediately, but will be returned to the background. However, if your application does not respond quickly enough, the operating system may terminate your application and generate a crash log. These events correspond to the following uiapplicationdelegate Methods: Application: Events: applicationwillresignactive: applicationdidenterbackground: applicationwillenterforeground: Events: applicationwillterminate: all the methods above, the application only has a limited time to complete processing. If it takes too long, the operating system terminates the application. Note: If you do not put operations that take a long time (such as network access) on the background thread, this situation is very likely to happen. For more information about how to avoid this situation, see the following two Tutorials: Grand Central Dispatch and nsoperations.
Forced user exitIOS 4.x supports multiple tasks. If the application blocks the interface and stops responding, You can terminate the application by double-clicking the Home button on the main screen. The application generates a crash log. Note: After double-clicking the Home button, you will see all applications that have run. Those applications may not be running or suspended. Generally, when you click the Home button, the application is retained for about 10 minutes in the background, and the operating system automatically terminates the application. Therefore, double-click the "home" button to display the Application List, indicating that it is a series of previously opened applications. Deleting the icons of those applications will not generate any crash logs.
Low memory terminationWhen You subclass uiviewcontroller, you may have noticed the didreceivememorywarning method. Applications running on the frontend have the highest optimization level for access and memory usage. However, this does not mean that the application can use all the available memory of the device-each application can only use a portion of the available memory. When the memory usage reaches a certain level, the operating system will send a uiapplicationdidreceivememorywarningnotification notification. Call the didreceivememorywarning method. At this time, in order to make the application continue to run normally, the operating system begins to terminate other applications in the background to release some memory. After all background applications are terminated, if your applications require more memory, the operating system will also terminate your applications and generate a crash log. In this case, background applications terminated do not generate crash logs.
Note:According to the Apple documentation, xcode does not automatically add low-memory logs. You must obtain logs manually. However, based on my personal experience, using xcode 4.5.2, low-memory logs will be automatically imported, but the "process" and "type" attributes are marked as unknown (unknown ). In addition, it is worth mentioning that allocating a large block of memory in a very short period of time will bring a huge burden to the system memory. In this way, a memory warning notification will also be generated.
Bugs in applicationsAs you may think, most crash events are caused by bugs in the application, so most crash logs are generated by bugs in the application. There are many types of bugs. In the second half of this tutorial, you will debug an application that contains bugs that will generate crash logs and learn how to locate and fix the problem!
Instances with Crash logsLet's take a look at a crash log instance, so that you have a good idea before dealing with some practical problems. It may not be too late. Meet your new friend: the report looks like a book. :) Let's explain it in a few parts: (1) The first part of process information is related to the crash process. Incident identifier is the unique identifier of the crash report. The crashreporter key is the unique key value corresponding to the device ID. Although it is not a real device identifier, it is also a very useful piece of information: If you see 100 crash logs with the same crashreporter key value, or only a few different crashreport values, this is not a common problem. It only occurs on one or a few devices. The hardware model identifies the device type. If many crash logs come from the same device type, it indicates that the application has problems only on a specific type of devices. In the above log, the device generated by the crash log is iPhone 4 s. Process is the application name. The number in the brackets is the ID of the process to be applied during the crash. The next few lines are self-explanatory and do not need to be repeated. (2) This section provides some basic information, including the date and time of the crash occurrence, and the IOS version of the device. If many crash logs come from IOS 6.0, it means the problem only occurs on iOS 6.0. (3) In this section, you can see the type of the exception thrown when the crash occurs. We can also see the Exception Code and the thread that throws the exception. Depending on the type of the crash report, you can see additional information in this section. (4) thread backtracking this part provides the Backtracking logs of all threads in the application. Rollback is a list of all active frames when a flash is triggered. It contains a list of functions called when a crash occurs. Take a look at the following line of log: it contains four columns: frame number -- Here is 2. Binary library name -- Here is the address of xyzlib. Call Method -- Here is 0x000048e88. The fourth column is divided into two child columns, one basic address and one offset. Here is 0 × 83000 + 8740. the first digit points to the file, and the second digit points to the code line in the file. (5) The thread status is the value in the flashback register. Generally, this part of information is not required, because the information in the Backtracking part is sufficient for you to find out the problem. (6) This Part of the binary image lists the binary files that have been loaded during crash.
Symbolic symbolicationThe first time you see the rollback on the crash log, you may think it is meaningless. We are used to the Method Name and number of rows, rather than the mysterious location like this: the process of converting these hexadecimal addresses into method names and number of rows is called symbolic. Several seconds after obtaining the crash log from the xcode organizer window, the crash log will be automatically signed. The version after the above line is symbolic is as follows: when xcode is a symbolic crash log, you need to access the application binary file corresponding to the app store and the. dsym file generated when the binary file is generated. It must be exactly matched. Otherwise, logs cannot be fully symbolic. Therefore, it is very important to retain the compiled versions distributed to users. When the application is archived before submission, xcode will save the binary file of the application. You can find all archived application files in the archives tab of xcode organizer. When a crash log is detected, if a matched. dsym file and application binary file exist, xcode automatically marks the crash log. If you switch to another computer or create a new account, you must move all the binary files to the correct location so that xcode can find them. (
Note:You must keep both the application binary file and the. dsym file to complete the symbolic crash log. Every time you submit a build to iTunes connect, you must archive it. The. dsym file and binary file are specifically bound to each build and subsequent build. Even if they are from the same source code file, each build is different from other builds and cannot be replaced with each other. If you use the build and archive commands, these files are automatically placed in the appropriate location. If you do not use the build and archive commands, place them in the location that can be searched by spotlight (such as the home directory .)
Low memory crashThe low memory crash log is slightly different from the general crash log, so this tutorial will explain it separately. When the iOS device detects low memory, the virtual memory system sends a notification requesting the application to release the memory. These notifications are sent to all running applications and processes, trying to reclaim some memory. If the memory usage remains high, the system will terminate the background thread to relieve the memory pressure. If the available memory is sufficient, the application will continue to run without generating a crash report. Otherwise, the application will be terminated by IOS and a low memory crash report will be generated. There is no stack tracing for application threads in the low-memory crash log. On the contrary, the memory usage of each process is measured in memory pages. (When writing this article, the size of a memory page is 4 kb .) The jettisoned text is displayed after the process name terminated by IOS due to memory release. If it appears after your application name, it indicates that your application is terminated because it uses too much memory. Low memory crash logs look like this: when an application experiences a low memory crash, you must check the memory usage in the application and how to handle the low memory warning. You can use allocations and leaks in the instruments tool to detect memory allocation problems and Memory leakage problems. If you do not know how to use instruments to check memory problems, take a look at this tutorial. Also, do not forget the virtual memory! The leaks and allocations of the instruments tool cannot track the memory usage. You must use VM tracker to view the memory usage. VM tracker is disabled by default. Enable instrument, manually select the automatic snapshoent flag, or press the snapshot now button. This tutorial will learn how to study low memory crash logs later.
Exception CodeBefore studying the real crash scenarios, we need to focus on the interesting exception codes. You can find the Exception Code in the reported exception section-section 3rd of the preceding code. Some codes are common. Generally, the Exception Code starts with some characters followed by one or more hexadecimal values. This value indicates the fundamental nature of flashback. From these codes, we can distinguish between program errors, invalid memory access, and other causes. Below are some common exception codes: 0x8badf00d: read "ate bad food "! (Replace the number with a letter, isn't it like: p) This encoding indicates that the app was terminated by IOS because of a watchdog timeout. Generally, an application takes too much time to start, terminate, or respond to system events. 0xbad22222: This encoding indicates that the VoIP application is terminated due to frequent restart. 0xdead10cc: read as "Dead Lock "! This Code indicates that the application occupies system resources when running in the background. For example, if the address book database is not released, the application is terminated. 0xdeadfa11: read as "Dead fall "! This Code indicates that the application is forcibly exited by the user. According to the Apple documentation, force exit occurs when the user presses the switch button until "slide to shut down" appears, and then press the Home button. Force exit will generate a crash log containing the 0xdeadfa11 Exception Code, because most of the logs force exit because the application blocks the interface. (
Note:Disabling suspended applications in the background task list does not generate crash logs. It is reasonable when an application is terminated once it is suspended. So no crash logs will be generated .) It's time to show your skills! Okay! You have learned all the basics of analyzing crash logs and fixing errors! Assume that you have just started working at rage-o-rage. The company has an application selling well on the App Store, called rage masters. Your boss Andy asked you to help solve the problem that several users often complain about the crash. Your task is to study the crash logs provided by users, find and fix the problems. You can download the application source code from here. (
Note:If you want to regenerate the crash report, follow the instructions below: 1. Download the source code and open the project file in xcode. 2. Use the correct provisioning profile to connect to the iOS device. 3. Select the iOS device from the xcode toolbar -- not the simulator as the target, and then build the application. 4. When you go to the default page (full screen image of the Application) on the device, immediately click the stop button on xcode. 5. Disable xcode. 6. Open the application directly on the device. 7. In the test scenario, connect the device to the computer and use xcode to obtain the crash log .)
Scenario 1: bad codeAn email from a user: "Big Brother, your application is a shit! I downloaded it to my own iPod Touch and iPhone, and to my son's iPod Touch. On all devices, the device is not turned on yet ......" Don't send an email from a user saying, "I downloaded your application and it will crash as soon as it is opened. Really sad reminder ..." Another email is more explicit: "Your application cannot run. I downloaded it to my wife and I. All devices are flushed when they are turned on ..." Okay, don't be discouraged! What are the secrets of these opinions? Let's look at the crash log: Have you found the problem? The Exception Code is 0x000000008badf00d. It is also reported later: This indicates that the application is flushed when it is started, and the watchdog mechanism of IOS terminates the application. Handsome! I found the problem, but why? Next, let's look at the log. Reads backtracing logs from the bottom up. The Bottom Frame (frame 25: libdyld. dylib) is called first, followed by frame 24, rage masters, main (main. M: 16), and so on. Frames related to application source code are the most important. The system library and framework are ignored. The next code-related frame is that the application will crash when executing the rmappdelegate (rmappdelegate. M: 35) Class Application: didfinishlaunchingwitexceptions: Method 35th line of code. Open xcode and check the line of code: It's it! Synchronously calling Web Services ?! On the main thread ?! In application: didfinishlaunchingwitexceptions: method ?!! Who wrote the code ?! Network callon the main thread makes kittens sad. You have to fix the problem anyway. This call must be performed asynchronously, or even more ideally, the Web Service is executed in other parts after application: didfinishlaunchingwitexceptions: Yes is returned. Calling in other places may require many modifications. Now, we only need to make the application do not crash. We can achieve better design in the future. Replace the above-line annoying code (and the following three lines of code) with the following asynchronous version:
Scenario 2: buttons that cannot respond to eventsOne user said, "I cannot add an rage master to a bookmarks. I want to roll back the application when I add it ..." One user said, "bookmarks cannot be used... On the details page, click the bookmarks button and the application will crash !" The above complaints are not very clear, and there must be a variety of causes. Look at the crash log: The Exception Code is SIGABRT. Generally, a SIGABRT exception is caused by an object receiving unimplemented messages. Or, in simple words, a nonexistent method is called on an object. This usually does not happen because object a calls Method B. If Method B does not exist, the compiler reports an error. However, if you use selector to call the method indirectly, the compiler cannot check whether the object exists in the method. Return to the crash log. It indicates that the crash occurs on a thread numbered 0. This means that a method that is not implemented by an object is probably called on the main thread. If you continue to read the tracing log, you will find that only frame 22, Main. M: 16, is related to your code, which does not help much. Continue to view the framework call. This is not your own code. But at least it confirms that the object calls an unimplemented method. Return to the rmdetailviewcontroller. M file, because it is the place where the bookmarked button is implemented. Find the code for the bookmarks function: it seems that there is no problem. Check the storyboard (XIB file) to confirm the correctness of the button connection. That's it! In mainstoryboard. storyboard, the button is connected to bookmarkbuttonpressed instead of bookmarkbuttonpressed (note that the semicolon below indicates that the method has a parameter ). You just need to modify the method signature to fix the problem: Of course, you can also simply delete the wrong connection on the XIB file and then reconnect the method, connect the XIB file to the correct method. Both methods are supported. Another problem was solved.
Scenario 3: Table bugsAnother user complained, "the bookmarks cannot be deleted in the bookmarks view ..." Another user complained about the same problem: "When I try to delete the bookmarks, the application will crash ..." These emails have no effect. Check the crash log! This looks like the previous crash log. Is another SIGABRT exception. You may want to know if it is the same: send information to an object that does not implement the corresponding method? Let's look back at the log to see which methods are called. Starting from the bottom, the final calling of your source code is frame 6: This is a method of uitableviewdatasource ?! There is no doubt that Apple has implemented this method-you can reload it, but it does not seem to have been implemented yet. In addition, this is an optional delegate method. Therefore, the problem is not to call an unimplemented method. Let's look at the above frames: frame 5. uitableview calls another method of its own deleterowsatindexpaths: withrowanimation: And then _ endcellanimationswithcontext: which looks like an apple internal method is called. Then, an exception occurs in the foundation framework. handlefailureinmethod: object: file: linenumber: Description:. These analyses are combined with user complaints. It seems that you have a bug in processing the uitableview row deletion process. Return to xcode. Do you know where to look? Can it be determined from the crash log? Row 68th of the rmbookmarksviewcontroller. M file: Have you found any problems? Let's take a closer look. Find it! What about the data source? The Code deletes a row in the table view, but does not modify the data source behind it. Replace the above Code with the following code to fix the problem: Done! Go! annoying bug !!
Scenario 4: crash when eating a lollipop!The user sent an email saying, "The application will crash when the rage master eats a lollipop ..." Another user said, "I asked the rage master to have a lollipop, and the application would crash in a few times !" The crash log is as follows: This log is much different from what we saw earlier. This is a low memory crash log from iOS 6. As we mentioned earlier, low memory crash logs are very different from other types of crash logs, which do not point to specific files or code lines. Instead, they draw a chart showing the memory usage on the device during crash. At least, the header is similar to other crash logs: Provides information such as incident identifier, crashreporter key, hardware model, and OS version. The next part is the low memory crash log unique: Free pages refers to the number of pages in the available memory. The size of each page is about 4 kb. In the preceding logs, the available memory is about 3,872 KB (or 3.9 MB ). Purgeable pages is the part of memory that can be cleared or reused. In the preceding log, It is 0 kb. Largest process is the name of the application that uses most of the memory for Flashback. In the above log, it is your application! Processes displays the list of processes and memory usage during crash. Contains the process name (first column), unique identifier of the process (second name), and memory pages used by the process (third column ). The last column shows the status of each application. In general, the frontmost is the status of the application that has a crash. Here is the rage masters, which uses 28591 pages (or 114.364 MB) of memory-this memory is too large! Through, the maximum process is the same as the frontmost state application, and it is also an application process that causes low memory crash. However, you may also see examples of different frontmost State applications. For example, if the maximum process is springboard, ignore it because the springboard process is an application that displays the home screen, and appears when you double-click the Home button, and it is always active. When low memory usage occurs, IOS sends a low memory warning to the active application and terminates the background application. If the front-end application continues to increase memory, IOS terminates it. To find the cause of low memory problems, you must use instruments to analyze the application. If you do not know how to do this, you can take a look at our tutorial on this aspect .. :] In addition, you can take shortcuts to respond to low-memory warning notifications to solve some crash problems. Go back to xcode to view the rmlollipoplicker. M file. This is the view controller for eating lollipops. Look at the source code: when the user clicks the run button, the application starts a background thread, calls the licklollipop method several times, and then updates the interface to reflect the number of lollipops. The licklollipop method reads a long string from the property list file (plist) and adds it to the array. This data is not important and can be re-created without affecting the user experience. It is a good habit to clear and recreate data without affecting user experience. In this way, the memory can be easily released to reduce the memory warning. So how can we improve the code quality? Implement the didreceivememorywarning method to process data as follows:
This article is an English version of an article which is originally in the Chinese language on aliyun.com and is provided for information purposes only. This website makes no representation or warranty of any kind, either expressed or implied, as to the accuracy, completeness ownership or
reliability of the article or any translations thereof. If you have any concerns or complaints relating to the article, please send an email, providing a detailed description of the concern or
complaint, to firstname.lastname@example.org. A staff member will contact you within 5 working days. Once verified, infringing content will be removed immediately.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
and provide relevant evidence. A staff member will contact you within 5 working days.