Mechanism
1. Frame pointers … the old default way
- Frame pointers are enabled by default.
- Strong optimization (“-O2”, “-O3”) will implicitly disable frame pointers.
2. Unwind tables … a separate binary section
- Unwind tables are enabled by default.
- Disabling exceptions (“-fno-exceptions”) may implicitly disable unwind tables.
Showcase
#include <stdio.h> void print() { printf("Test"); *((char*)NULL) = 0; } int main() { print(); return 0; }
With backtrace
% clang++ test.cpp -w -O1 -fno-inline % lldb a.out (lldb) r Target 0: (a.out) stopped. (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x100003f84) * frame #0: 0x0000000100003f84 a.out`print() + 20 frame #1: 0x0000000100003f94 a.out`main + 12 frame #2: 0x000000018249f154 dyld`start + 2476
Without backtrace
% clang++ test.cpp -w -O1 -fno-inline -fomit-frame-pointer -fno-unwind-tables % lldb a.out (lldb) r Target 0: (a.out) stopped. (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x100003f8c) * frame #0: 0x0000000100003f8c a.out`print() + 16