There are a number of tools available which help debugging segmentation faults and I would like to add my favorite tool to the list: Address Sanitizers (often abbreviated ASAN).
Modern¹ compilers come with the handy -fsanitize=address
flag, adding some compile time and run time overhead which does more error checking.
According to the documentation these checks include catching segmentation faults by default. The advantage here is that you get a stack trace similar to gdb's output, but without running the program inside a debugger. An example:
int main() { volatile int *ptr = (int*)0; *ptr = 0; }
$ gcc -g -fsanitize=address main.c $ ./a.out AddressSanitizer:DEADLYSIGNAL ================================================================= ==4848==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x5654348db1a0 bp 0x7ffc05e39240 sp 0x7ffc05e39230 T0) ==4848==The signal is caused by a WRITE memory access. ==4848==Hint: address points to the zero page. #0 0x5654348db19f in main /tmp/tmp.s3gwjqb8zT/main.c:3 #1 0x7f0e5a052b6a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26b6a) #2 0x5654348db099 in _start (/tmp/tmp.s3gwjqb8zT/a.out+0x1099) AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV /tmp/tmp.s3gwjqb8zT/main.c:3 in main ==4848==ABORTING
The output is slightly more complicated than what gdb would output but there are upsides:
There is no need to reproduce the problem to receive a stack trace. Simply enabling the flag during development is enough.
ASANs catch a lot more than just segmentation faults. Many out of bounds accesses will be caught even if that memory area was accessible to the process.
¹ That is Clang 3.1+ and GCC 4.8+.