|
Mark, one of my colleagues, fixed syntax error in your code. That makes the code works on IA-32.
================== t2.cpp for IA32 ================ #define _POSIX_SOURCE 199309
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <execinfo.h> #include <setjmp.h> #include <unistd.h>
#define __USE_GNU 1 #include <sys/ucontext.h>
void MyStackWalker (siginfo_t *info, void *my_eip) { void *trace[10]; int i; int trace_size = 0; char **messages = (char**)NULL; trace_size = backtrace(trace, 10); messages = backtrace_symbols(trace, trace_size); ucontext_t *uc = (ucontext_t *)my_eip; trace[1] = (void*)uc->uc_mcontext.gregs[REG_RIP]; for (i=0; i<trace_size; i++) { printf("\n[bt] %s", messages[i]); } free (messages); } void MySignalHandler (int signo, siginfo_t *info, void *my_eip) { if (signo == SIGFPE) { printf("\n A floating point exception has been detected."); MyStackWalker(info, my_eip); } else if (signo == SIGSEGV) { printf("\n A segmentation violation has been detected."); MyStackWalker(info, my_eip); } else if (signo == SIGILL) { printf("\n An illegal operation has been detected."); MyStackWalker(info, my_eip); } else if (signo == SIGTRAP) { printf("\n A out of bounds array has been detected."); MyStackWalker(info, my_eip); } else { printf("\n An unknown exception has been detected."); MyStackWalker(info, my_eip); } } int main() { struct sigaction newAct; newAct.sa_sigaction= &MySignalHandler; sigemptyset (&newAct.sa_mask); newAct.sa_flags = SA_RESTART | SA_SIGINFO; sigaction(SIGFPE, &newAct, NULL); sigaction(SIGILL, &newAct, NULL); sigaction(SIGSEGV, &newAct, NULL); sigaction(SIGTRAP, &newAct, NULL); } ============================================
$ icc -V Intel(R) C Compiler Professional for applications running on IA-32, Version 11.0 Build 20090609 Package ID: l_cproc_p_11.0.084 Copyright (C) 1985-2009 Intel Corporation. All rights reserved.
$ icpc t2.cpp $ g++ t2.cpp $
However, above code doesn't compile on Intel 64. Then I did some further investigation.It looks that REG_EIP only works on IA-32. In /usr/include/sys/ucontext.h, you may see something like this
#if __WORDSIZE == 64 ... enum { REG_R8 = 0, # define REG_R8 REG_R8 REG_R9, # define REG_R9 REG_R9 REG_R10, # define REG_R10 REG_R10 REG_R11, ... REG_RIP, # define REG_RIP REG_RIP ... };
#else /* __WORDSIZE == 32 */
enum { ... REG_EIP, # define REG_EIP REG_EIP REG_CS, # define REG_CS REG_CS REG_EFL, # define REG_EFL REG_EFL REG_UESP, # define REG_UESP REG_UESP REG_SS # define REG_SS REG_SS }; #endif
So, on IA-32, REG_EIP is an enum value. But on Intel 64, REG_EIP is not defined. It seems that you should use REG_RIP instead on Intel 64. With this modification, t2.cpp compiles. See below.
=========== t2.cpp for Intel 64 ================ #define _POSIX_SOURCE 199309
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <execinfo.h> #include <setjmp.h> #include <unistd.h>
#define __USE_GNU 1 #include <sys/ucontext.h>
void MyStackWalker (siginfo_t *info, void *my_eip) { void *trace[10]; int i; int trace_size = 0; char **messages = (char**)NULL; trace_size = backtrace(trace, 10); messages = backtrace_symbols(trace, trace_size); ucontext_t *uc = (ucontext_t *)my_eip; trace[1] = (void*)uc->uc_mcontext.gregs[REG_RIP]; for (i=0; i<trace_size; i++) { printf("\n[bt] %s", messages[i]); } free (messages); } void MySignalHandler (int signo, siginfo_t *info, void *my_eip) { if (signo == SIGFPE) { printf("\n A floating point exception has been detected."); MyStackWalker(info, my_eip); } else if (signo == SIGSEGV) { printf("\n A segmentation violation has been detected."); MyStackWalker(info, my_eip); } else if (signo == SIGILL) { printf("\n An illegal operation has been detected."); MyStackWalker(info, my_eip); } else if (signo == SIGTRAP) { printf("\n A out of bounds array has been detected."); MyStackWalker(info, my_eip); } else { printf("\n An unknown exception has been detected."); MyStackWalker(info, my_eip); } } int main() { struct sigaction newAct; newAct.sa_sigaction= &MySignalHandler; sigemptyset (&newAct.sa_mask); newAct.sa_flags = SA_RESTART | SA_SIGINFO; sigaction(SIGFPE, &newAct, NULL); sigaction(SIGILL, &newAct, NULL); sigaction(SIGSEGV, &newAct, NULL); sigaction(SIGTRAP, &newAct, NULL); } =======================================
$ icc -V Intel(R) C Intel(R) 64 Compiler Professional for applications running on Intel(R) 64, Version 11.0 Build 20090609 Package ID: l_cproc_p_11.0.084 Copyright (C) 1985-2009 Intel Corporation. All rights reserved.
$ icpc t2.cpp $ g++ t2.cpp $
|