30

I'm learning iPhone programming from Erica Sadun's The iPhone Developer's Cookbook. When I run the app I created by following the steps in the Temperature Conversion Example starting on page 81 in the simulator, it terminates due to an uncaught exception. (See http://groups.google.com/group/iphonesdk/browse_frm/thread/6f44a90fdb8da28a?hl=en for the question I posted to the iPhoneSDK Google Group.)

The exception is thrown after calling UIApplicationMain() from my main(). If I look through the stack trace in the debugger, all I see is (of course) assembly. How do I find out what kind of exception was thrown?

Update:
Learning the details of the exception from the Debugger Console was enough to help me solve the problem. (See http://groups.google.com/group/iphonesdk/browse_frm/thread/6f44a90fdb8da28a?hl=en.) I verified that I could set a symbolic breakpoint on objc_exception_throw, but I didn't look to see if the backtrace from there would have been helpful.

Forge
  • 6,538
  • 6
  • 44
  • 64
Daryl Spitzer
  • 143,156
  • 76
  • 154
  • 173

4 Answers4

53

Put a breakpoint at objc_exception_throw and run your app via Debug instead of Run

To clarify, what you're actually seeing when you get an exception without the breakpoint is the same stack trace always - it's the uncaught exception handler. The type of exception is logged to the Run console, but if you want to see a backtrace for where the exception was raised, that's what the breakpoint is for.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • 2
    Hit ⌘⌥B, select Run → Show → Breakpoints, or select Run → Manage Breakpoints → Add Symbolic Breakpoint. – Lily Ballard Dec 21 '08 at 20:38
  • 56
    After you stop in the debugger, you can enter `po $eax` (simulator) or `po $r0` (device) to see the exception. This is because the exception object is passed as the first argument to objc_exception_throw, which is kept in register r0 or EAX. HTH – nielsbot Jan 23 '12 at 04:43
  • 3
    In Xcode 4.5.2 you can find it at: Product → Debug → Create Symbolic Breakpoint... – Jay Haase Dec 01 '12 at 13:30
  • 3
    Also make sure that you have selected "objc_exception_throw" in the debug navigator and not the bothersome "main.m" while entering "po $eax". – Klaas Sep 08 '13 at 22:51
  • 5
    @EthanHolshouser: No it's not. The simulator uses the host architecture of your computer. The only difference is when simulating an arm64 binary, the simulator will run x86_64 instead of i386, which makes it `$rdi` instead of `$eax`. Similarly, on an actual arm64 device, you probably want `$x0` instead of `$r0`. – Lily Ballard Sep 22 '14 at 23:16
  • @EthanHolshouser: I actually tested before commenting, on the off chance that they were in fact translating the register name. `po $r0` did not work in an iPhone 6 simulator in Xcode 6.1 beta. I tried both armv7 and arm64 simulation. – Lily Ballard Sep 23 '14 at 19:04
  • 2
    Interestingly, on the arm64 simulator (which is x86_64), there's synonyms `$arg1`, `$arg2`, etc for the registers, so you don't have to remember `$rdi`. Unfortunately this isn't true on the armv7 simulator (which is i386). I don't know if it's true for device debugging because I'm not set up at the moment to actually run code on a device. You can see if this is true with `register read -A`, which prints the "alternate name" for each register, if there is one. – Lily Ballard Sep 23 '14 at 19:08
  • Also, `HTH` means `hope it helps` for others that are used to read words. – Iulian Onofrei Jul 21 '15 at 08:07
  • @nielsbot, For me, `$eax` doesn't work no more, instead, I use `$rax`. – Iulian Onofrei Jul 21 '15 at 08:21
  • $eax is 32-bit vs $rax is 64-bit x86-64 I believe. Also looks like $arg1 may work based on @KevinBallard's comment. – nielsbot Jul 22 '15 at 17:07
15

In the new Xcode (at least starting from v4.5), you can catch all exceptions easily by doing this:

  1. Bring up breakpoint navigator (⌘6)
  2. Click + on the bottom left
  3. Add Exception Breakpoint

I think the above is the same as a breakpoint on objc_exception_throw. http://samwize.com/2012/09/26/xcode-4-dot-5-tips-and-tricks/

samwize
  • 25,675
  • 15
  • 141
  • 186
6

http://ijoshsmith.com/2011/11/28/debugging-exceptions-in-xcode-4-2/

Same as samewize's solution, but also shows how to make this breakpoint show up by default in all your projects (right click on breakpoint, Move Breakpoint To, User).

Dale
  • 133
  • 1
  • 7
3

As Kevin answered, you will find more helpful debugging info by setting a breakpoint at objc_exception_throw.

If you are using Xcode 4.2, you can add this symbolic breakpoint by going to Breakpoint Navigator > Click on the add icon on the bottom left > Add symbolic breakpoint > Enter objc_exception_throw for Symbol > Done.

samwize
  • 25,675
  • 15
  • 141
  • 186
  • Better late than never. This shall be the first thing I do for every project henceforth. Super useful. Thanks Daryl Spitzer, @kevin-ballard and samwize – trss Sep 29 '12 at 05:59