16

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. Invoking this function will stop my program, launch the debugger, and display a callstack of the line that called __debugbreak().

Is there anything similar to __debugbreak() for the iPhone? I've tried Debugger(), but that gives me a linker error.

Thanks, Claus

8 Answers8

26

edit

Turns out this also works:

#define Debugger() { raise( SIGINT ) ; }

I think it's the same principle.


I use this:

#define Debugger() { kill( getpid(), SIGINT ) ; }

I think it works in the simulator and on the device.. no assembly required!

nielsbot
  • 15,922
  • 4
  • 48
  • 73
  • 1
    I can confirm that this works perfectly on both the device and the simulator. Thanks so much! Wish I could mark it accepted... – Bill Apr 20 '11 at 01:33
6

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.)

  • 1
    asm("trap") did not work for me, FYI. It behaves the same way as assert from assert.h (you can not continue when it's triggered). – Dave May 14 '10 at 00:08
1

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.

rpetrich
  • 32,196
  • 6
  • 66
  • 89
  • Works for me. I would also note that the code listed above will give "implicit declaration" compiler warnings. Add the declaration of the function immediately above the #ifdef DEBUG.. void _MyAssert(int val); Also, for an iPhone project I found putting the function implementation in main.c works nicely. – ohhorob Dec 03 '09 at 19:14
0

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.

Jens Alfke
  • 1,946
  • 12
  • 15
  • Manually setting a breakpoint is not an option for asserts because those asserts are all over the place. I'm looking for a way to trigger a break on demand from within my code. –  Jul 19 '09 at 03:16
0

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.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
  • I think the problem is that you can not resume execution in the debugger from this method. – Dave May 14 '10 at 00:07
0

While an ancient thread, found this while researching same topic for Xcode 7. What solved this for me was a feature called "Create Exception Breakpoint..."

Debug > Breakpoints > Create Exception Breakpoint...

This puts a special breakpoint in the Breakpoint Navigator (under View > Navigators > Show Breakpoint Navigator).

breakpoint navigator pane showing All Exceptions breakpoint

This breaks on the actual throw of the exception:

[ exception raise ]

without terminating your code execution. You can just continue if that is how your code is structured.

Double-clicking the break point marker next to "All Exception" lets you adjust where and how the exception break point stops:

break point navigator showing options on for how and when breakpoint occurs

Cerniuk
  • 14,220
  • 2
  • 29
  • 27
0

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/

Ohad Kravchick
  • 1,154
  • 11
  • 15
-1

Check out conditional breakpoints:

http://www.cocoabuilder.com/archive/message/xcode/2008/10/22/25358

Dan Lorenc
  • 5,376
  • 1
  • 23
  • 34