I am writing an infrastructure code which should log backtrack of my crashed C program exactly as gdb does, but without using gdb specially. For that I have written a crash signal handler to log just before exitting.
#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void crash_signal_handler(int sig)
{
void* backtrace_array[10];
size_t size;
char** symbols;
size = backtrace(backtrace_array, 10);
symbols = backtrace_symbols(backtrace_array, size);
int fd = fileno(stdout); // Use stdout file descriptor
fprintf(stderr, "Program crashed. Backtrace:\n");
backtrace_symbols_fd(backtrace_array, size, fd);
free(symbols);
exit(1);
}
int main() {
signal(SIGSEGV, crash_signal_handler);
//Intentionally trigger a segmentation fault for testing
int* ptr = NULL;
*ptr = 42;
}
However, its backtrace is no where similar to what we see in GDB when the program crashes, and we run bt command.
/home/ravi# ./a.out
Program crashed. Backtrace:
./a.out(crash_signal_handler+0x35)[0x55931304e27e]
/lib/x86_64-linux-gnu/libc.so.6(+0x43090)[0x7fbf3155f090]
./a.out(main+0x3a)[0x55931304e335] -----> no line number shown, file name is also a.out it should be source file name where it crashed
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x7fbf31540083]
./a.out(_start+0x2e)[0x55931304e18e]
/home/ravi#
ideally it should show the line number and name of the source file like below
(gdb) r
Starting program: /home/root# a.out
**Program received signal SIGSEGV, Segmentation fault.
0x000055555555513d in main () at sample.c:7
7 *ptr = 42;
(gdb) bt
#0 0x000055555555513d in main () at sample.c:7
(gdb)** q
A debugging session is active.
Inferior 1 [process 1567493] will be killed.
Quit anyway? (y or n) y
/home/root#
Is there any way to update the code and achieve this? This will be helpful to debug the large source code based C program if it crashed in production environment.
Also, it is ok to write a signal handler to log to backtrack and add that feature in the production code? I know we can not permanently keep symbols in production code, but during testing phase it can be ok. Or anything better can be done ? Any suggestion are welcome.