views:

428

answers:

1

Right now when one of my asserts is triggered in Xcode, I get the assert message, and a dump of the stack, which is full of numbers that are not very meaningful to me.

In order to get a trace of the call stack, it requires me to debug the application, and run it up to the point where the assert occurred, and hope that it asserts again. For bugs that are 100% reproducible, this isn't too huge of a problem, but is still a waste of time.

It would be much better if I got a call stack trace every time an assert is hit.

How do you define an assert macro that will dump a call stack trace in Xcode?

+2  A: 

NSThread has a class method called callStackSymbols (and NSException has an instance method of the same name). Sorry, I don't regularly use exceptions and don't regularly use asserts either (not proud of either fact), so I'm not sure what the assertion macro should do.

#define AssertWithStackSymbols(x) \
do { \
    if (!(x)) { \
        NSLog (@"%s failed assertion\n%@", #x, [NSThread callStackSymbols]); \
        abort(); \
    } \
} while(0) 

Or, as KennyTM kindly pointed out, you can use backtrace_symbols. There is even a method that outputs the symbols directly to a file descriptor, backtrace_symbols_fd.

#define AssertWithStackSymbols(x) \
do { \
    if (!(x)) { \
        void *stack[128]; \
        int count; \
        fputs (#x " failed assertion.\n", stderr); \
        count = backtrace (stack, sizeof stack / sizeof (void *)); \
        backtrace_symbols_fd (stack, count, STDERR_FILENO); \
    } \
while (0)
dreamlax
Oh, forgot to mention: the `callStackSymbols` method is only available on Mac OS X 10.6.
dreamlax
On OS X 10.5 and iPhoneOS you can use `backtrace_symbols(3)`.
KennyTM