#include #include #include #include #include #include #include #include #include #define SCP_FROM_UCONTEXT(uc) \ ((struct sigcontext *) &((struct ucontext *)(uc))->uc_mcontext) static int _traceback_signal = -1; static pthread_t pid1 = 0; static pthread_t pid2 = 0; static pthread_t pidmain = 0; extern int __libc_allocate_rtsig(int high); static void tb_sig_handler(int sig, siginfo_t *info, void *ucontext) { struct sigcontext *scp; int ret, i; printf("\n%s entered\n", __func__); printf("thread 0x%lx context\n", pthread_self()); scp = SCP_FROM_UCONTEXT(ucontext); printf("rIP: %16.16lx\n", scp->rip); printf("rSP: %16.16lx\n", scp->rsp); printf("rBP: %16.16lx\n", scp->rbp); printf("\n"); } void * test_thread1(void *arg) { while(1) { sleep(2); }; return NULL; } void * test_thread2(void *arg) { while(1) { sleep(2); }; return NULL; } int main() { struct sigaction act; int ret = 0; _traceback_signal = __libc_allocate_rtsig(1); act.sa_sigaction = tb_sig_handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART | SA_SIGINFO; sigaction(_traceback_signal, &act, NULL); ret = pthread_create(&pid1, NULL, test_thread1, NULL); if(ret < 0) { fprintf(stderr, "thread 1 creation failed\n"); return -1; } printf("Thread 1 (0x%lx) created\n", pid1); ret = pthread_create(&pid2, NULL, test_thread2, NULL); if(ret < 0) { fprintf(stderr, "thread 2 creation failed\n"); return -1; } printf("Thread 2 (0x%lx) created\n", pid2); pidmain = pthread_self(); printf("Main pid: 0x%lx\n", pidmain); ret = pthread_kill(pid1, _traceback_signal); if(ret >= 0) { printf("pid1[0x%lx] signaled\n", pid1); } sleep(1); ret = pthread_kill(pid2, _traceback_signal); if(ret >= 0) { printf("pid2[0x%lx] signaled\n", pid2); } sleep(1); #if 0 ret = pthread_kill(pidmain, _traceback_signal); if(ret >= 0) { printf("pidmain[0x%lx] signaled\n", pidmain); } #endif return 0; }