Locate most segmentation faults with a one-liner
If you write C programs, you probably have already used GDB or at least heard of it. Even if you feel attached to it, I suggest you to give LLDB a go. In my experience, it is much more stable (remember that time you lost all your debugging progress because your session got messed up or GDB outright crashed... yeah...) and consistent in its functionality. Obviously, it has about 30 years of hindsight to help!
The following general syntax when used with a program compiled with at least -g option on your favorite compiler, prints out where it thinks the error happens and a stack trace with meaningful names, then exits.
$ lldb -b <program_name> [<arg>..] -o "r" -k "bt" -k "q"
The caveat is there are bugs living in deeper circles of hell that corrupt your memory in ways so unimaginable that the stack frames are corrupted and you don't get a legible output back. Yet, it will work most of the time!
Here's a simple example that dereferences the NULL pointer, crashes, and burns.
// crash_and_burn.c #include <stdio.h> void crash(char *str); void burn(char *str); int main(int argc, char *argv[]) { char *null_str = 0; printf("%s\n",argv[1]); printf("%s\n",argv[2]); crash(null_str); return 0; } void crash(char *str) { burn(str); } void burn(char *str) { *str = 'M'; }
It is compiled with the following:
$ gcc -g crash_and_burn.c -o crash_and_burn
and debugged with the following:
$ lldb -b crash_and_burn HELLO! HI! -o "r" -k "bt" -k "q"
(lldb) target create "crash_and_burn" Current executable set to 'crash_and_burn' (x86_64). (lldb) settings set -- target.run-args "HELLO!" "HI!" (lldb) r HELLO! HI! Process 77826 stopped * thread #1: tid = 0x6cc3c3, 0x0000000100000f8c crash_and_burn`burn(str=0x0000000000000000) + 12 at crash_and_burn.c:22, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0) frame #0: 0x0000000100000f8c crash_and_burn`burn(str=0x0000000000000000) + 12 at crash_and_burn.c:22 19 } 20 21 void burn(char *str) { -> 22 *str = 'M'; 23 } Process 77826 launched: '/Users/mistralcontrastin/p/c/playground/crash_and_burn' (x86_64) (lldb) bt * thread #1: tid = 0x6cc3c3, 0x0000000100000f8c crash_and_burn`burn(str=0x0000000000000000) + 12 at crash_and_burn.c:22, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0) * frame #0: 0x0000000100000f8c crash_and_burn`burn(str=0x0000000000000000) + 12 at crash_and_burn.c:22 frame #1: 0x0000000100000f75 crash_and_burn`crash(str=0x0000000000000000) + 21 at crash_and_burn.c:18 frame #2: 0x0000000100000f4c crash_and_burn`main(argc=3, argv=0x00007fff5fbff678) + 92 at crash_and_burn.c:12 frame #3: 0x00007fff95fb15ad libdyld.dylib`start + 1 frame #4: 0x00007fff95fb15ad libdyld.dylib`start + 1 (lldb) q
As you can see you have everything from the source line that crashed it to the function calls leading to it with their arguments at the time!
If you're interested in dissecting the one-liner, check lldb --help for options and [0] for their arguments (the link is especially useful for GDB afficionados).
[0] http://lldb.llvm.org/lldb-gdb.html