Useful Xcode breakpoints

Here I will document useful breakpoints when you're developing for OSX or iOS with Xcode. This is primarily for me to remember what is useful as I am googling some of these all the time.

It's sad that there are no "breakpoint-templates" that will automatically apply to all Xcode projects that you'll ever create. But enough of the introductory words, here comes the list:

Objective C exception breakpoint

Obviously the most important breakpoint there is, this one has a "template" of some sort as it has its very own menu entry:

Objective C Exception Breakpoint

So far so good, but the annoying thing is that the exception message will not be printed when the breakpoint is reached but only if you continue (and crash your program for real, and of course void your stack backtrace)

So add this to the default:

i386/iOS simulator (32Bit)

Objective C Exception Breakpoint modifications

Just add the following actions:

  • po *(id*)($esp+4)

which will print for example:

-[__NSCFConstantString characterAtIndex:]: Range or index out of bounds
(lldb) 

x86_64/iOS simulator (64Bit)

Use the following actions:

  • po $rdx
  • po $rcx
  • po $r8

iOS device (ARM/ARM64)

Use these:

  • po $r2
  • po $r3
  • po *(id*)($sp)

If all this is to verbose to you look at the prebuild lldb script from here: http://qwan.org/2013/06/18/how-to-snatch-the-error-code-from-the-trap-frame-in-xcode/

Memory errors

Attention: This may be superseeded by the new Address sanitizer in Xcode 7

Sometimes it happens that you find a nasty memory error that is not at all obvious where it came from. Mostly it appears somewhere far away from the original error because the stack was smashed or a buffer overflow bleed into neighboring variables and overwrote something.

To find those errors you'll usually first enable all the memory protection error loggers that are available:

Memory debugging

And now you'll add a symbolic breakpoint at malloc_error_break to catch the offender that is smashing your stack right away (or at least very near to the cause)

Core Graphics Errors

All of Core Graphics error logging will go through the function CGPostError so it is sensible to add a breakpoint at exactly that location. It will break at anything Core Graphics will spit out. You know those 'XXX tried to draw to a nil context` errors may be hard to find if a lot is going on in your application at the same time.

Slow loading views

Perhaps because you used a wrong font-name? Who knows! Set a symbolic breakpoint to CTFontLogSuboptimalRequest to be notified when Core Text does not find the font directly but has to resort to a detailed search (that is very slow, on an iPad 4 it takes about 3 seconds to complete)

Auto layout

This one is obvious when it happens. But it's better to catch it directly instead of waiting for one to happen so for completeness, set a symbolic breakpoint to UIViewAlertForUnsatisfiableConstraints

Improve the debugger

Sometimes lldb can be quite stubborn:

(lldb) p self.window.bounds
error: property 'bounds' not found on object of type 'UIWindow *'
error: 1 errors parsing expression

But this can be fixed:

(lldb) expr @import UIKit
(lldb) p self.window.bounds
(CGRect) $4 = (origin = (x = 0, y = 0), size = (width = 375, height = 667))

Wow, much better, but what has this to do with breakpoints you may ask? Just try the following: Set a new breakpoint in your app delegate that is hit immediately after starting your application, set it to auto-continue and add an action expr @import UIKit.

The next run of your app will stop briefly at that breakpoint, execute that command and continue running. If you hit any other breakpoint (or press pause) the command already has been executed and lldb knows everything about UIKit already! Great!

(You may want to @import Foundation and @import CoreGraphics too)

Johannes Schriewer

iOS and Linux developer. Tinkers with electronics and 3D-Printers, loves low-level stuff.

Augsburg, Germany, Planet Earth