How to generate backtrace with symbols and function name, when a program crashes

compilation command

neelkanth@ubuntu:~$ gcc -rdynamic test.c 

Stack Trace Output, when the code crashed with SIGSEGV

neelkanth@ubuntu:~$ ./a.out 
Entry func1 57
Entry: func3 34
Entry dummycrash 64
Entry: signalhandler 14
-- STACK TRACE START
0 ./a.out(signalhandler+0x77) [0x5568234ef2e0]
1 /lib/x86_64-linux-gnu/libc.so.6(+0x46210) [0x7f46fbe78210]
2 ./a.out(dummycrash+0x35) [0x5568234ef4f2]
3 ./a.out(func3+0x2f) [0x5568234ef3ff]
4 ./a.out(func2+0x12) [0x5568234ef431]
5 ./a.out(func1+0x2f) [0x5568234ef49d]
6 ./a.out(main+0x5b) [0x5568234ef579]
7 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x7f46fbe590b3]
8 ./a.out(_start+0x2e) [0x5568234ef1ae]
Exit: signalhandler 25
Sending PID: 2107, UID: 1000

C program:

 neelkanth@ubuntu:~$ cat test.c 

#include <stdio.h>

#include <unistd.h>

#include <signal.h>

#include <string.h>

#include <execinfo.h>

#include <stdlib.h>


void signalhandler(int signo)

{

int nptrs, i;

void *buffer[1024];

char **strings;


printf("Entry: %s %d\n", __func__, __LINE__);

printf("-- STACK TRACE START\n");

nptrs = backtrace(buffer, 1024);

strings = backtrace_symbols(buffer, nptrs);

if (strings == NULL) {

return ;

}   

for (i = 0; i < nptrs; ++i) {

printf("%d\t%s\n", i, strings[i]);

}

printf("Exit: %s %d\n", __func__, __LINE__);

printf("Sending PID: %ld, UID: %ld\n", getppid(), getuid());

exit(-1);

}

void func3()

{

printf("Entry: %s %d\n", __func__, __LINE__);

dummycrash();

printf("Exit: %s %d\n", __func__, __LINE__);

return;

}

void func2()

{

        func3();

printf("Entry: %s %d\n", __func__, __LINE__);

printf("Exit: %s %d\n", __func__, __LINE__);

return;

}

void func1()

{

printf("Entry %s %d\n", __func__, __LINE__);

func2();

printf("Exit: %s %d\n", __func__, __LINE__);

return;

}

void dummycrash()

{

printf("Entry %s %d\n", __func__, __LINE__);

char *temp = NULL;

        strcpy(temp, "crash");

printf("Exit: %s %d\n", __func__, __LINE__);

}


int main (int argc, char *argv[])

{

int nptrs, i;

void *buffer[1024];

char **strings;


signal(SIGSEGV, signalhandler);

func1();

while (1)

sleep (10);

return 0;

}