Signal Handler on a Linux system.
We are moving our software baseline from a Unix operating system to a Linux operating system. I am trying to change our unix signal handler to use the linux based signal routines. I have to trap the following signals: SIGFPE, SIGILL, SIGSEGV, and SIGTRAP. The signal handler works using the following simple routine #1 layout, but I cannot get and print the stack frame as it is when the signal/exception occurs. It gives me the stack frame as it is after the signal has been trapped. I then researched on the internet, and found out that this is a problem that a lot of people have, and their fix was to use the routine #2 layout. I cannot get routine #2 to compile using the icc compiler. I have tried a lot of different #define options, but that just generates a different set of compiler errors. If anyone has ever done this before, could you please show me the code that works using the icc compiler.
Routine #1 layout:
#define _POSIX_SOURCE 199309
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <execinfo.h>
#include <setjmp.h>
void MyStackWalker (void)
{
void *trace[10];
int i;
int trace_size = 0
char **messages = (char**)NULL;
trace_size = backtrace(trace, 10);
messages = backtrace_symbols(trace, trace_size);
for (i=0; i<trace_size; i++)
{
printf("n[bt] %s", messages[i]);
}
free (messages);
}
void MySignalHandler (int signo)
{
If (signo == SIGFPE)
{
printf("n A floating point exception has been detected.");
MyStackWalker();
}
else if (signo == SIGSEGV)
{
printf("n A segmentation violation has been detected.");
MyStackWalker();
}
else if (signo == SIGILL)
{
printf("n An illegal operation has been detected.");
MyStackWalker();
}
else if (signo == SIGTRAP)
{
printf("n A out of bounds array has been detected.");
MyStackWalker();
}
else
{
printf("n An unknown exception has been detected.");
MyStackWalker();
}
}
Int main()
{
struct sigaction newAct;
struct sigaction oldAct;
newAct.sa_handler = MySignalHandler;
sigemptyset (&newAct.sa_mask);
newAct.sa_flags = 0:
sigaction(SIGFPE, NULL, &oldAct);
if (oldAct.sa_handler != SIG_IGN)
{
sigaction(SIGFPE, &newAct, NULL);
}
sigaction(SIGILL, NULL, &oldAct);
if (oldAct.sa_handler != SIG_IGN)
{
sigaction(SIGILL, &newAct, NULL);
}
sigaction(SIGSEGV NULL, &oldAct);
if (oldAct.sa_handler != SIG_IGN)
{
sigaction(SIGSEGV, &newAct, NULL);
}
sigaction(SIGTRAP, NULL, &oldAct);
if (oldAct.sa_handler != SIG_IGN)
{
sigaction(SIGTRAP, &newAct, NULL);
}
}
Routine #2 layout
#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
#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);
trace[1] = (void*)ux->uc_mcontext.gregs[REG_EIP];
messages = backtrace_symbols(trace, trace_size);
ucontext_t *uc = (ucontext_t *)my_eip;
for (i=0; i<trace_size; i++)
{
printf("n[bt] %s", messages[i]);
}
free (messages);
}
void MySignalHandler (int signo, siginfo_t *into, 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);
}
|