Hello,
I am working on a Motorola VME 167 card with a 68040 processor. The card is running debian linux 2.2 (kernel 2.2.10). The application I am developing needs to handle signals and needs to know the cause of the signal. For example, if the application executes a divide by zero instruction then it should know in the signal handler if this was the cause. For this the application checks the value of ‘siginfo_t->si_code’ passed to the signal handler. However, this value seems to always zero. Following is an example program which does not work:
#include <stdio.h> #include <signal.h> #include <ucontext.h>
void my_signal_handler(int sig, siginfo_t *sigInfo, struct ucontext *scp); stack_t st;
static union { char buffer[SIGSTKSZ]; long double ld; long l; void *p } alt_sig_stack;
main() { struct sigaction sa; int i, j; st.ss_flags = 0; st.ss_sp = alt_sig_stack.buffer; st.ss_size = sizeof(alt_sig_stack.buffer); if (sigaltstack(&st, 0) != 0) printf("sigaltstack failed\n"); sa.sa_flags = SA_SIGINFO | SA_ONSTACK; sa.sa_sigaction = my_signal_handler;
sigaction(SIGFPE, &sa, NULL); j = 10; i = 0; i = j / i; }
void my_signal_handler(int sig, siginfo_t *sigInfo, struct ucontext *scp) { printf("D0 = %x\n", scp->uc_mcontext.gregs[R_D0]); printf("D1 = %x\n", scp->uc_mcontext.gregs[R_D1]); printf("D2 = %x\n", scp->uc_mcontext.gregs[R_D2]); printf("A0 = %x\n", scp->uc_mcontext.gregs[R_A0]); printf("A1 = %x\n", scp->uc_mcontext.gregs[R_A1]); printf("A2 = %x\n", scp->uc_mcontext.gregs[R_A2]); printf("SP = %x\n", scp->uc_mcontext.gregs[R_SP]); printf("PC = %x\n", scp->uc_mcontext.gregs[R_PC]); printf("siginfo->si_code = %d\n", sigInfo->si_code); printf("siginfo->si_addr = %d\n", sigInfo->si_addr); printf("ss_sp = %d\n", scp->uc_stack.ss_sp); printf("FPE_INTDIV = %d\n", FPE_INTDIV); }
The above program outputs 0 for si_code where as it should be printing 1 (FPE_INTDIV). Does any body have any solution for this? This seems to be a problem with the kernel. Does any release of the kernel (post 2.2.10) have a fix for this?
Regards, Harish
|