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