Signal Handler on a Linux system.

Feilong H. (Intel)
Total Points:
1,697
Status Points:
1,197
Brown Belt
July 2, 2009 2:30 AM PDT
Rate
 
#3

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
$


Intel Software Network Forums Statistics

8488 users have contributed to 31626 threads and 100713 posts to date.
In the past 24 hours, we have 36 new thread(s) 123 new posts(s), and 186 new user(s).

In the past 3 days, the most popular thread for everyone has been gemm(A,A,A) like possible? The most posts were made to gemm(A,A,A) like possible? The post with the most views is Dear Steve, excuse me for a d

Please welcome our newest member chat1983