#define _GNU_SOURCE
#include <stdio.h>
 #include <signal.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <execinfo.h>
 #include <ucontext.h>
/*
  * backtrace和bacetrace_symbols打印出回溯信息
  */
  
 #if 0
 #include <execinfo.h>
int backtrace(void **buffer, int size);
 char **backtrace_symbols(void *const *buffer, int size);
 void backtrace_symbols_fd(void *const *buffer, int size, int fd);
#endif
 static void signal_handler(int sig, siginfo_t *info, void *ctx)
 {
     ucontext_t *context = (ucontext_t *)ctx;
    /* dump registers, x64 CPU specific */
     printf( "Signal = %d  Memory location = %p\n"
             "RIP = %016X  RSP = %016X  RBP = %016X\n"
             "RAX = %016X  RBX = %016X  RCX = %016X\n"
             "RDX = %016X  RSI = %016X  RDI = %016X\n"
             "R8  = %016X  R9  = %016X  R10 = %016X\n"
             "R11 = %016X  R12 = %016X  R13 = %016X\n"
             "R14 = %016X  R15 = %016X  RFLAGS = %016X\n\n",
             sig, info->si_addr,
             context->uc_mcontext.gregs[REG_RIP],
             context->uc_mcontext.gregs[REG_RSP],
             context->uc_mcontext.gregs[REG_RBP],
             context->uc_mcontext.gregs[REG_RAX],
             context->uc_mcontext.gregs[REG_RBX],
             context->uc_mcontext.gregs[REG_RCX],
             context->uc_mcontext.gregs[REG_RDX],
             context->uc_mcontext.gregs[REG_RSI],
             context->uc_mcontext.gregs[REG_RDI],
             context->uc_mcontext.gregs[REG_R8],
             context->uc_mcontext.gregs[REG_R9],
             context->uc_mcontext.gregs[REG_R10],
             context->uc_mcontext.gregs[REG_R11],
             context->uc_mcontext.gregs[REG_R12],
             context->uc_mcontext.gregs[REG_R13],
             context->uc_mcontext.gregs[REG_R14],
             context->uc_mcontext.gregs[REG_R15],
             context->uc_mcontext.gregs[REG_EFL]);
    /* get call stack and write to stdout */
     void *buf[256] = {0};
     int size = backtrace(buf, 256);
     backtrace_symbols_fd(buf, size, fileno(stdout));
     exit(-1);
 }
void test_3(int *p)
 {
     *p = 1;
 }
void test_2(int *p)
 {
     test_3(p);
 }
void test_1(int *p)
 {
     test_2(p);
 }
int main(int argc, char *argv[])
 {
     int *p = 0x12345678;
    struct sigaction action;
     sigemptyset(&action.sa_mask);
     action.sa_sigaction = signal_handler;
     action.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &action, NULL);
    test_1(p);
     return 0;
 }
// gcc -rdynamic backtrace2.c -o backtrace2
 #if 0
000000000000143f <test_3>:
     143f:    f3 0f 1e fa              endbr64
     1443:    55                       push   %rbp
     1444:    48 89 e5                 mov    %rsp,%rbp
     1447:    48 89 7d f8              mov    %rdi,-0x8(%rbp)
     144b:    48 8b 45 f8              mov    -0x8(%rbp),%rax
    144f:    c7 00 01 00 00 00        movl   $0x1,(%rax)                 // SIGSEGV
     1455:    90                       nop
     1456:    5d                       pop    %rbp
     1457:    c3                       retq   
0000000000001458 <test_2>:
     1458:    f3 0f 1e fa              endbr64
     145c:    55                       push   %rbp
     145d:    48 89 e5                 mov    %rsp,%rbp
     1460:    48 83 ec 08              sub    $0x8,%rsp
     1464:    48 89 7d f8              mov    %rdi,-0x8(%rbp)
     1468:    48 8b 45 f8              mov    -0x8(%rbp),%rax
     146c:    48 89 c7                 mov    %rax,%rdi
     146f:    e8 cb ff ff ff           callq  143f <test_3>
     1474:    90                       nop
     1475:    c9                       leaveq
     1476:    c3                       retq   
0000000000001477 <test_1>:
     1477:    f3 0f 1e fa              endbr64
     147b:    55                       push   %rbp
     147c:    48 89 e5                 mov    %rsp,%rbp
     147f:    48 83 ec 08              sub    $0x8,%rsp
     1483:    48 89 7d f8              mov    %rdi,-0x8(%rbp)
     1487:    48 8b 45 f8              mov    -0x8(%rbp),%rax
     148b:    48 89 c7                 mov    %rax,%rdi
     148e:    e8 c5 ff ff ff           callq  1458 <test_2>
     1493:    90                       nop
     1494:    c9                       leaveq
     1495:    c3                       retq   
Signal = 11  Memory location = 0x12345678
 RIP = 000000000C0E744F  RSP = 00000000029CAB30  RBP = 00000000029CAB30
 RAX = 0000000012345678  RBX = 000000000C0E7540  RCX = 00000000317BE166
 RDX = 0000000000000000  RSI = 00000000029CAA20  RDI = 0000000012345678
 R8  = 0000000000000000  R9  = 0000000000000000  R10 = 0000000000000008
 R11 = 0000000000000246  R12 = 000000000C0E7140  R13 = 00000000029CAD20
 R14 = 0000000000000000  R15 = 0000000000000000  RFLAGS = 0000000000010202
./backtrace2(+0x1407)[0x56150c0e7407]           // backtrace
 /lib/x86_64-linux-gnu/libc.so.6(+0x43090)[0x7f38317be090]
 ./backtrace2(test_3+0x10)[0x56150c0e744f]       // SIGSEGV
 ./backtrace2(test_2+0x1c)[0x56150c0e7474]       // test_2 -> test3
 ./backtrace2(test_1+0x1c)[0x56150c0e7493]       // test_1 -> test2
 ./backtrace2(main+0x86)[0x56150c0e751c]         // main -> test_1
 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x7f383179f083]
 ./backtrace2(_start+0x2e)[0x56150c0e716e]
#endif