Tuesday, January 5, 2010

Debugging from crash files

I know this is something no developer ever wants to do, but sometimes it's necessary. You've deployed your iPhone app, and through no fault of your own (we don't code bugs, right? ;) ) some user finds a way to break your app. I mean, who really thought they'd actually click THAT button you put in the middle of the screen and says "CLICK ME!!!!"?
Ok, blame aside, you now have a crash report you need to do something with. Looking at the file, all you see is memory addresses, which, last time I checked, not a lot of developers could take that, and tell you what happened and where it happened. So, what do you do?
Well, fortunately, Apple has given iPhone developers tools to use to map those memory addresses to actual methods and line numbers. The good news is, those tools work really well. the bad news, you need a little more information. The key here lies really in 3 files, that all have to match builds. The first is obvious: the .crash file. The other two, you generated your self, the .app file and a file in the same directory as the .app file, the .dSYM file.
The short version is, the app file is a stripped binary file, meaning all the debugging information has been removed. In iPhone apps, this information lives in the .dSYM file.
To use the .crash file, here's what you're likely going to need to do:
1) Open the .crash file in either console or your favorite text editor (even XCode if you so desire)
2) look for something like "Crashed Thread:" which will tell you which thread caused the problem.
3) in the trace for that thread, which will start with something like "Thread 0 Crashed:" you'll see a bunch of libraries and memory addresses. Look for something from your app. You may see things like libobjc.A.dylib or libstdc++..., Foundation, CoreFoundation, UIKit... In that same area, you'll see something with your apps name.
4) Take, probably the highest, row in the list with your app name, and copy the address, which will start 0x... like 0x00004d42 for example. You'll need this later.
5) In a terminal window, navigate to the directory in which the .app and .dSYM file live. I copy these off to a directory I use for deployed apps, in my case, /Users//Development/distToAppStore//
6) Start gdb with your app. If your apps name is HelloWorld.app, you'd start gdb (from the directory in your terminal like: "gdb HelloWorld.app"
7) now, you have gdb running, type "info line *0x00004d42" where the address is the address you pasted earlier. You'll see something that resembles the line, file and method that crashed, such as
Line 213 of "" starts at address 0x42ca <-[ ]+390> and ends at 0x42d0 <-[ ]+396>

Now you have a great starting point to to find out what happened and fix your app, making your iPhone apps more stable!

No comments:

Post a Comment