Now, I recalled back in the mists of time that there was a nice way to take an OSX crash log and extract the line number, but for some reason I couldn’t make my brain give me the information beyond the fact that I needed to use atos. Now that I’ve unraveled the bits and pieces I already knew, I figured I’d drop it in a blog post so that I could recall it later (when I inevitably forget once more).

What is this “atos” of which you speak?

The atos command converts numeric addresses to their symbolic equivalents. If full debug symbol information is available, for example in a .app.dSYM sitting beside a .app, then the output of atos will include file name and source line number information. Mac OS X Developer Tools Reference

Buh? Don’t worry, that’s just some fancy talk from the Apple docs. What it means is that if you give atos your application’s binary and a starting memory address it can tell you things about related memory addresses, including the source file and line number.

Great, so how do I use it?

To begin, open up your crash log and scroll all the way down to the “Binary Images” section. You should see the name of your application on the first line. The very first HEX number is the starting address:

Next, I need the address where the bad things happened in my app. To get this, scroll up to the top of your crash log and look for the “Application Specific Backtrace” section. There are probably a number of lines here, but what you want to locate is the specific call out for your app.

From the example above, I want to grab 0x000000010ae5e276. This tells me where my app tried to be bad an insert items out of turn. Now, I’m ready to put it all together and get the mystery reveal on the offending source code.

In the first line, I’ve provided the command. The “o” option is for the binary. In this case, I’m looking at the NewsBee app and drilling down to the compiled executable. The “l” option is used to specify the load address I want atos to use when bringing the binary into memory. The final number is the place where the code went wonky.

On execution, atos loads up the binary and helpfully repeats my explanation above in obfuscated language. Then, it’s kind enough to tell me right where the problem is: line 325 in newsBeeController.m. As it turns out, the problem is happening right where I expected it to be (the _loadMenu function), but knowing for sure is awesome because the error itself is difficult to replicate.

Of course, everything I’ve said here can be gleaned by simply reading the man page for atos, but why do that when you can google, right? 😉