How to print call stack in Swift?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Swift provides Thread.callStackSymbols to get the current call stack as an array of strings. Each string represents a stack frame with the binary name, address, function name, and offset. This is useful for debugging, logging crash contexts, and understanding execution flow. For production crash reporting, use structured frameworks like os_log or third-party tools like Sentry or Firebase Crashlytics instead.
Thread.callStackSymbols
Output (debug build):
Each line contains: frame index, binary name, address, demangled symbol name, and byte offset.
Thread.callStackReturnAddresses
For programmatic access, use the raw return addresses:
Return addresses are NSNumber values. You can symbolicate them later with atos or dSYM files.
Using in a Custom Logger
Assertions and Preconditions with Stack Traces
Swift's assertionFailure and preconditionFailure automatically print the call stack. You can also create custom assertion helpers:
Exception Handler for Uncaught Exceptions
Capture the stack trace when an uncaught Objective-C exception occurs:
This handler catches Objective-C exceptions (NSException) but not Swift runtime errors (fatalError, preconditionFailure).
Signal Handlers for Swift Crashes
For pure Swift crashes (EXC_BAD_ACCESS, SIGABRT):
Signal handlers are limited — you cannot allocate memory or call most functions safely. For production, use a crash reporting framework.
Symbolication
In release builds, symbols are stripped. Stack traces show addresses instead of function names:
To symbolicate, use atos:
os_log and OSSignposter (Modern Approach)
For structured debugging in production:
os_log messages are captured by Console.app and can be filtered by subsystem and category.
Common Pitfalls
- Mangled symbols in release builds: Without dSYM files, release build stack traces show hexadecimal addresses. Always archive dSYM files for every release build. Xcode Archives include them automatically.
- Performance overhead of
callStackSymbols: Generating human-readable symbols is expensive (involves dladdr lookups). Do not callThread.callStackSymbolsin hot code paths. UsecallStackReturnAddressesif you only need raw addresses for later symbolication. - Signal handler limitations: Signal handlers run in a restricted context. Calling
print(), allocating memory, or using Objective-C runtime functions in a signal handler is undefined behavior. Usewrite()(POSIX) for minimal crash logging. - Missing frames due to tail call optimization: The compiler may optimize tail calls, removing frames from the stack. In debug builds (
-Onone), all frames appear. In release builds (-O), some intermediate frames may be missing. - NSSetUncaughtExceptionHandler does not catch Swift errors: Swift's
fatalError(), array out-of-bounds, and force-unwrap failures are not Objective-C exceptions. The uncaught exception handler only catchesNSException. Use signal handlers for Swift runtime crashes.
Summary
- Use
Thread.callStackSymbolsto get the current call stack as an array of readable strings - Use
Thread.callStackReturnAddressesfor raw addresses (faster, for later symbolication) - In release builds, use dSYM files and
atosto translate addresses to function names and line numbers - Use
NSSetUncaughtExceptionHandlerfor Objective-C exceptions and signal handlers for Swift crashes - Avoid calling
callStackSymbolsin performance-critical code — it is expensive - For production apps, use structured logging (
os_log) and crash reporting frameworks (Sentry, Crashlytics)
Related reading
- How to print out all the elements of a List in Java?
- How to print the current Stack Trace in .NET without any exception?
- How to process SQS queue with lambda function not via scheduled events?
- How to properly define hash function for a list of objects?
- How to print details of a 'catch all' exception in Swift?
- How to print to the console in Android Studio?
- How to print the value of a Tensor object in TensorFlow?
- How to print to the console in Android Studio?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.