I'd like to log the call trace during certain points, like failed assertions, or uncaught exceptions.
7 Answers
This code works on any thread:
NSLog(@"%@", NSThread.callStackSymbols);
Returns an array containing the call stack symbols. Each element is an
NSString
object with a value in a format determined by thebacktrace_symbols()
function.

- 18,845
- 10
- 77
- 85

- 11,740
- 2
- 39
- 59
-
15New in Mac OS X 10.6, which didn't exist when this question was originally asked. For pre-Snow-Leopard, use the `backtrace` and `backtrace_symbols` functions; see the backtrace(3) manpage. – Peter Hosey Feb 25 '10 at 13:32
-
6Only on iOS 4.0 and above. – Danra Mar 28 '11 at 08:42
-
Thanks! Is there a way to make this only print the stack trace, say, 6 levels down instead of all the way? – sudo Jul 29 '14 at 16:33
-
9000, use `backtrace/backtrace_symbols` directly – dymv Feb 27 '15 at 15:10
-
2@sudo It's an array so just define range `[NSThread.callStackSymbols subarrayWithRange:NSMakeRange(0, MIN(6, NSThread.callStackSymbols.count))];` – Albert Renshaw Mar 22 '22 at 04:46
n13's answer didn't quite work - I modified it slightly to come up with this
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
int retval;
@try{
retval = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
@catch (NSException *exception)
{
NSLog(@"Gosh!!! %@", [exception callStackSymbols]);
@throw;
}
return retval;
}
}

- 37,241
- 25
- 195
- 267

- 3,229
- 1
- 35
- 34
-
4Gah... Apple should make this a standard at least while developing an application. A bunch of memory addresses is... archaic – Russ Sep 11 '13 at 20:02
-
-
1This *doesn't* work in all situations. This is a better approach if you want to catch all uncaught exceptions: http://codereview.stackexchange.com/questions/56162/unhandled-exception-handler-that-captures-a-screenshot (The code in that question is a little overcomplicated, but it also does more than simply log the call stack symbols.) – nhgrif Jul 12 '14 at 21:57
-
You can add `NSLog(@"[Error] - %@ %@", exception.name, exception.reason);` if you want the actual exception too – Corentin S. Mar 25 '15 at 15:02
Cocoa already logs the stack trace on uncaught exceptions to the console although they're just raw memory addresses. If you want symbolic information in the console there's some sample code from Apple.
If you want to generate a stack trace at an arbitrary point in your code (and you're on Leopard), see the backtrace man page. Before Leopard, you actually had to dig through the call stack itself.
-
6Apparently available in iOS 4 but not 3.2. Here's what I used, shamelessly copied from the backtrace man page: #include
... void* callstack[128]; int i, frames = backtrace(callstack, 128); char** strs = backtrace_symbols(callstack, frames); for (i = 0; i < frames; ++i) { printf("%s\n", strs[i]); } free(strs); – mharper Aug 28 '10 at 22:10 -
Being called in HandleException it writes back trace of handler function itself, while [NSException callStackSymbols] shows stack of the place where exception has raised. But if you replace "backtrace(...)" with: "NSArray arr = [ex callStackReturnAddresses]; int frames = arr.count; for (i = 0; i < frames; ++i) callstack[i] = (void) [((NSNumber *) [arr objectAtIndex:i]) intValue];" you will get current exception stack trace. This is how [NSException callStackSymbols] works, I suppose: traces they return are equal and in both app calls are replaced by _mh_execute_header in release. – Tertium Sep 28 '12 at 19:38
This pretty much tells you what to do.
Essentially you need to set up the applications exception handling to log, something like:
#import <ExceptionHandling/NSExceptionHandler.h>
[[NSExceptionHandler defaultExceptionHandler]
setExceptionHandlingMask: NSLogUncaughtExceptionMask |
NSLogUncaughtSystemExceptionMask |
NSLogUncaughtRuntimeErrorMask]

- 37,241
- 25
- 195
- 267

- 3,573
- 26
- 28
-
1Note, though that this will only work within a registered exception handler (not, e.g., in a @catch block) – Barry Wark Oct 23 '08 at 00:13
For exceptions, you can use the NSStackTraceKey member of the exception's userInfo dictionary to do this. See Controlling a Program's Response to Exceptions on Apple's website.

- 85,404
- 22
- 176
- 172