For assert macros in my iPhone project, I\'m looking for a way to programmatically break into the debugger. On Windows (MSVC++), I can use __debugbreak() for this purpose. I
Check out conditional breakpoints:
http://www.cocoabuilder.com/archive/message/xcode/2008/10/22/25358
I just set a breakpoint at the place I want to stop. Xcode remembers breakpoints persistently, so any time I run the app with gdb, it'll stop at that point.
If you want to break on assertion failures, a good place to set a breakpoint is on the function objc_exception_throw, in the Objective-C runtime, which is what actually throws an exception. Use the Run > Show > Breakpoints window and double-click the "Double-click for symbol" row, then type the name.
A helpful person on Apple's developer forum gave me the tip to use asm("trap")
when running on the device and asm("int3")
when running on the simulator. This makes the program break into the debugger if you started your programm in debug mode (Option-Command-Y).
(__builtin_trap()
also breaks into the debugger, but you can't continue afterwards. assert(false)
terminates the program with a message, but doesn't break into the debugger.)
First Add -DDEBUG
to OTHER_CFLAGS
on your debug target; this will define the DEBUG
symbol when building a debug build.
Then add a simple assert macro to your prefix header:
#ifdef DEBUG
#define MyAssert(val) _MyAssert(val)
#else
#define MyAssert(val) do { } while(0)
#endif
Next create a _MyAssert
function in a module somewhere:
#ifdef DEBUG
void _MyAssert(int expression)
{
if (expression == 0) {
NSLog(@"Assertion failed!"); // Place breakpoint here
}
}
#endif
Finally create a breakpoint on the NSLog
line.
Is there something wrong with the simple assert() macro? Something like
assert(pointerToTest != nil);
will halt your process at that point if the condition is not true. If running under the debugger, you'll be presented with a stack trace of calls that led to the failed assertion. If you want to trigger it every time you hit a certain code path, you could do
assert(false);
I find these assertions extremely useful for verifying that all IBOutlets are non-nil when a window or view is brought up from a NIB.
If you run your program in debug, your app should launch the debugger when it reaches an invalid assertion.
For it to stop, as Jens Alfke tried to say, you need to enable "Stop on Objective-C Exceptions" (under the Run menu).
For more info about debugging vs. releasing and asserts, read http://myok12.wordpress.com/2010/10/10/to-use-or-not-to-use-assertions/