More Fun With Exceptions in Cocoa

Ever wonder what the problem is when Xcode is catching on an exception deep within the cocoa libraries because you’ve got break on all exceptions on? Many of these can be a little confusing because despite the fact that an exception was thrown your app seems to run fine afterwards.

I was curious too, but Apple is using C++ exceptions in many of the core libraries so there’s no object to catch and break on to grab the info (unless you want to convert the class to Objective C++ and use C++ exceptions yourself).

You can however dig into the stack trace and get the exception information from the registers themselves1.
These are the steps I used.

  1. Select the __cxa_throw stack frame in the Debug Navigator.
  2. In the variables view of the debug, where it normally says “Auto”, you want to select “All”.
  3. Under “General Purpose Registers” we are looking for two specific registers2.
    1. r3 which I will call the exception reason.
    2. r10 which I will call the exception data.
  4. Right click on each of these registers and select “View Value As” -> “Custom Type…”
  5. In the popover that appears change (unsigned int)$r3 to (char *)$r3

Thats it, you should now see two environment variables in your list with intelligible output. I was trying to instantiate a UIImage from NSData I got from the web and there was an error in the meta data so I got the following

  • $r3 = "Duplicate property or field node"
  • $r10 = "pmtm:Version"

If you want to ignore the inner library exceptions just select “Objective-C” when creating your exception breakpoint.

  1. The exception I was encountering and investigating was in the ImageIO framework which is used by CoreImage, UIImage, etc to create images. I don’t know if the registers used vary from framework to framework. 

  2. Register r12 also holds a bunch of data but I have no clue what it is. I was originally using call (void)printf("%s", `$r12`) to inspect the register contents so a bunch of text came out that looked like backslash hex encoded UTF8 with a bunch of extra chars. decoding it as a UTF8 string did not produce better results. My suspicion is that it is a pointer to the exception handler but the suspicion is pretty baseless, If anyone knows drop me a line.