Wednesday, May 20, 2009

Debugging iPhone Crashes

Sometimes, developing iPhone applications can be very frustrating. Debugging crashes and memory issues can be very time consuming if one does not know how. Unfortunately, most books on iPhone programming either devote less than a chapter on debugging or, in most cases, totally skip it.

This post tries to de-mystify debugging crashes. When I say crashes, I mean straightforward exceptions (and not the memory access errors).

Typically, release builds are stripped of debug symbols to prevent reverse engineering (and other kinds of 'abuse') and to keep the released binary small in size. But, by doing so, you end up with only bunch of cryptic addresses in the log and absolutely no information on where the problem is (unlike in Java stack traces which pin-point the source of the exception).

On iPhone, typically, when the application is built, in the build folder (where the .app file is located), you will also find a file with a '.dSYM' extension, that contains a copy of the symbol information in the executable. This file maintains a one-to-one relationship between the source code and the compiled object code, which could make it possible to correlate an execution address with a line of code in the original source. I found that .dSYM files are generated by default. But it is a good idea to check your project settings in Xcode and ensure that 'Generate Debug Symbols' is checked.



Next, grab a copy of ratos. ratos is a ruby script that symbolicates the entire stack trace using atos (address to symbol) tool. The script is very simple to use and extremely helpful. Here is a sample output:

App Name:AtosDemo
App Path:/Users/ajeya/Documents/workspace/AtosDemo

Paste xcode stack trace to stdin, then type 'sim' or 'arm' on a line by itself.
Type 'exit' or '^D' to quit and 'app' to print the current app.

ratos>Stack: (
2483900683,
2534657595,
2483900139,
2483900202,
2478626815,
2478092680,
10809,
816608399,
10391,
816111650,
816149355,
2478330414,
2483403557,
2483403992,
827745792,
827745989,
816114848,
816160924,
10308,
10162
)
sim

-[AtosDemoViewController viewDidLoad] (in AtosDemo) (AtosDemoViewController.m:36)
-[AtosDemoAppDelegate applicationDidFinishLaunching:] (in AtosDemo) (AtosDemoAppDelegate.m:21)
main (in AtosDemo) (main.m:14)
start (in AtosDemo) + 54


Detailed instructions on how to use the script can be found on the script's homepage.

Of course, you can also choose to use 'atos' directly. But, I found ratos to be much more convenient.

Here are some useful links on debugging on iPhone and Xcode:
  1. ratos source on github
  2. Symbolification
  3. Debugging and Symbolizing Crash Dumps in Xcode
  4. Stacktraces
Reblog this post [with Zemanta]

No comments: