/* gcc -g -Wall -o test_sighandler -rdynamic test_sighandler.c GNU/Linux: ./test_sighandler Got signal 11, faulty address is 0xdeadbeef, from 5597bd471de0 Executable name = '/home/srs/Hurd/DEBs/test_cases/test_sighandler�', len = 47 GNU/Hurd: ./test_sighandler Got signal 4 Executable name = './test_sighandler', len = 21 Changing 0xdeadbeef to 0xbeadbeef gives: ./test_sighandler Got signal 11, faulty address is 0xbeadbeef, from 8048986 Executable name = './test_sighandler', len = 21 */ #define _GNU_SOURCE #include #include #include #include #include #include #include /* get REG_EIP/REG_RIP from ucontext.h */ #include const char* getExecutableName() { char link[1024]; char exe[1024]; //snprintf (link, sizeof link, "/proc/%d/exe", getpid()); snprintf (link, sizeof link, "/proc/self/exe"); if(readlink (link, exe, sizeof link)==-1) { fprintf(stderr,"ERRORRRRR\n"); exit(1); } int len = strlen(exe); exe[len] = '\0'; printf("Executable name = '%s', len = %d\n", exe, len); return 0; } void bt_sighandler(int sig, siginfo_t *info, void *secret) { void *trace[16]; char **messages = (char **)NULL; int i, trace_size = 0; ucontext_t *uc = (ucontext_t *)secret; /* Do something useful with siginfo_t */ if (sig == SIGSEGV) #ifdef __x86_64__ printf("Got signal %d, faulty address is %p, " "from %llx\n", sig, info->si_addr, uc->uc_mcontext.gregs[REG_RIP]); #else printf("Got signal %d, faulty address is %p, " "from %x\n", sig, info->si_addr, uc->uc_mcontext.gregs[REG_EIP]); #endif else printf("Got signal %d\n", sig); trace_size = backtrace(trace, 16); /* overwrite sigaction with caller's address */ #ifdef __x86_64__ trace[1] = (void *) uc->uc_mcontext.gregs[REG_RIP]; #else trace[1] = (void *) uc->uc_mcontext.gregs[REG_EIP]; #endif messages = backtrace_symbols(trace, trace_size); /* skip first stack frame (points here) */ getExecutableName(); printf("[bt] Execution path:\n"); for (i=1; i