Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ksylvan/9ab6944f05d078c8aa33042db8d44636 to your computer and use it in GitHub Desktop.
Save ksylvan/9ab6944f05d078c8aa33042db8d44636 to your computer and use it in GitHub Desktop.
How to symbolize a crash dump in Mac OS X, given a crash dump or exception log. Includes some steps and tips I've collected that are missing in Apple's TN2123. One time I tried this using lldb instead of gdb but it didn't work.
********************************************************
*** STEPS TO SYMBOLIZE A CRASH DUMP OR EXCEPTION LOG ***
********************************************************
1) Move/copy both the crashing .app and the relevant.dSYM files into the same directory.
2) If the crash was in a framework, dynamic library, or bundle, you have position-independent code and must work out the *slide*. Otherwise, skip up to step 9 and use slide=0.
3a) If you have a crash dump, look in the *Binary Images* part of the crash log and find the framework, dynamic libray or bundle in which the crash occurred. Read the first column of the output. This is the address at which the __TEXT segment was loaded. We call it the *Actual Load Address* and denote it as *A*.
3b) If instead you have an exception log, like this:
2 CoreFoundation 0x00007fff907c234a -[NSArray arrayByAddingObject:] + 138
3 MyFramework 0x0000000100152704 MyFramework + 614850
4 MyFramework 0x0000000100152cd5 MyFramework + 616339
5 MyFramework 0x00000001000395db MyFramework + 202203
6 Foundation 0x00007fff92f34677 __NSThreadPerformPerform + 225
Find at the *lowest* call in MyFramework, line 5 in this case. As Nick Blievers pointed out to me, subtract the second number given from the first number to get the *Actual Load Address *A* of the framework.
A = 0x00000001000395db - 202203 = 0x100008000
You should get a number that is a multiple of 0x1000. If so, it's a pretty good chance that this is the Actual Load Address *A*.
4) Open a Terminal window and cd to the the directory of step 1).
5) Run the following command:
otool -l <MyApp.app/or/else/path/to/framework> | grep -B 3 -A 8 -m 1 "__TEXT"
Example:
otool -l BookMacster.app/Contents/Frameworks/Bkmxwork.framework/Bkmxwork | grep -B 3 -A 8 -m 1 "__TEXT"
If that doesn't give 3+1+8=12 lines of text, that is because the -A and -B options in grep seem to be broken in Mountain Lion. Do the grep manually. Example:
otool -l BookMacster.app/Contents/Frameworks/Bkmxwork.framework/Bkmxwork
then scroll up to the top of the result and read the first 12 lines.
You will get output which looks like this:
Load command 0
cmd LC_SEGMENT
cmdsize 464
segname __TEXT
vmaddr 0x00000000
vmsize 0x00111000
fileoff 0
filesize 1118208
maxprot 0x00000007
initprot 0x00000005
nsects 6
flags 0x0
7) Note the value given for vmaddr. We call this the *Intended Load Address* and denote it as *I*. I've never seen anything other than 0x0.
8) Calculate the *slide* = A - I
9) Enter "gdb" with no options, unless your crash report is from a different architecture. Then, you must make sure you use the correct -arch flag. Example, if the crash occurred on a PowerPC and you are not running now on a PowerPC: 'gdb -arch ppc'. If the crash occurred when running a 32-bit app on an Intel Mac and you are running on a 64-bit Intel Mac: 'gdb -arch i386'
10) Enter the command 'set sharedlibrary preload-libraries no'. This disables the behavior described above.
11) Load your binary with the 'file' command.
Example for main executable:
file Bookdog.app/Contents/MacOS/Bookdog
Example for framework (note that it's OK to use the symlink in the framework)
file BookMacster.app/Contents/Frameworks/Bkmxwork.framework/Bkmxwork
12) Load the relevant dSYM library, for example:
add-dsym Bkmxwork.framework.dSYM
(Note: Usually this step is not necessary because gdb will find it in a Spotlight search under the hood. But Spotlight is only 80% reliable.
13) Look at the crash report and find the first interesting address in the call stack. For example, in
12 com.myCompany.MyApp 0x0002ef5f 0x1000 + 254908
the address is 0x0002ef5f
14) If you calculated a slide, tell gdb to get info for the address minus the slide:
(gdb) info line *(<address> - <slide>)
Example:
(gdb) info line *(0x0002ef5f - 0x1000)
If gdb has an answer, it will display it like this:
Line 117 of "/Users/jk/Documents/Programming/Projects/Bookdog/BookdogTableColumn.m"
starts at address 0x2ef4e <-[BookdogTableColumn dataCellForRow:]+1033>
ends at 0x2ef61 <-[BookdogTableColumn dataCellForRow:]+1052>
Repeat the preceding two steps for other interesting addresses
For further information:
http://developer.apple.com/library/mac/technotes/tn2004/tn2123.html#SECUSINGDSYM
http://www.cocoabuilder.com/archive/message/xcode/2008/2/26/19750
*******************************************************
*** STEPS TO GET GRANULARITY TO LINE NUMBER -- EEK! ***
*******************************************************
As you can see, this is a real pain. Usually, after you've isolated the crash to a method, your time will be better spent examining the method's code and thinking "what if" at each line. But if you *must* put yourself through the torture of translating the offset to a line number, first of all, slap yourself on the face for writing such long methods. Then, here you go:
On Dec 2, 2009, at 4:55 PM, Graham Cox wrote:
> When I get a stack trace in a crash report, as exampled below, can I use the offsets (+71, +50) to locate the relevant line in the source code? What do these numbers actually mean?
>
> 1 com.apptree.drawkit 0x001c7bb9 -[DKDrawableObject encodeWithCoder:] + 71
> 2 com.mapdiva.ortelius 0x0003c81d -[DKOSymbol encodeWithCoder:] + 50
This reply from Greg Parker of Apple, "Runtime Wrangler"
http://lists.apple.com/archives/cocoa-dev/2009/Dec/msg00138.html
Ask gdb for the line number for that function+offset. (Note the actual address may not match the one in the crash log.)
(gdb) x/i '-[DKDrawableObject encodeWithCoder:]' + 71
0x4bb9 <-[DKDrawableObject encodeWithCoder:]+71> ...
(gdb) info line *0x4bb9
Line 55 of "DKDrawableObject.m" starts at address 0x4bb9 <-[DKDrawableObject encodeWithCoder:]+71> and ends at 0x4bc9 <-[DKDrawableObject encodeWithCoder:]+87>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment