Messages in this thread | | | From | "John Chris Wren" <> | Subject | Question about signal handling | Date | Thu, 14 Jun 2001 01:33:08 -0400 |
| |
Hopefully I'm not asking a really stupid question here, but...
When setting up a signal handler, using sa_handler, there is a quasi-documented 2nd parameter of 'struct context ctx' passed to the signal handler. This seems to work on 2.2.12, 2.2.18, and 2.4.5-ac2. According to various documents, when using sa_siginfo (and setting SA_SIGINFO), the third parameter to the handler is defined as a 'void *', but actually passes a 'ucontext_t' data type. Which is not defined in any kernel code, except for the sparc64 branch. Casting this to a 'struct context' or a 'struct context *' doesn't seem to achieve the desired results on any of the three kernels I tested.
Google searches indicate different things. POSIX 1 compliance says it should be a 'ucontext_t *' (www.opengroup.org/onlinepubs/007908799/xsh/sigaction.html+sigcontext+siginf o_t+sigaction&hl=en&lr=lang_en) (I realize that's the Open standard, but the comments at the bottom talk about POSIX compliance). Other searches say it returns as a 'struct context *'.
I tried following the code through the kernel, but I'm not familiar enough with yet to really understand how it's getting scheduled, and exactly which parameters are getting passed back.
What is the correct behavior supposed to be? And if using sa_siginfo, how does one get at the context parameters to find the EIP the fault occurred at?
Here's a sample bit of code I used for testing. Leaving #define SIGACTION demonstrates the third parameter not (seemingly) being passed as a context pointer, #undef demonstrates the sa_handler 2 paramter handler, which returns a correct context.
#include <stdio.h> #include <signal.h> #include <errno.h> #include <string.h>
#define SIGACTION
#ifdef SIGACTION void fSegvHandler (int sigNo, siginfo_t *si, void *p) { struct sigcontext *context = (struct sigcontext *) p; #else void fSegvHandler (int sigNo, void *p) { struct sigcontext *context = (struct sigcontext *) &p; #endif
printf ("\nContext: %08X\n",context); fflush (stdout); printf ("gs: %04X\tfs: %04X\tes: %04X\tds: %04X\n" "edi: %08X\tesi: %08X\tebp: %04X\tesp: %04X\n" "ebx: %08X\tedx: %08X\tecx: %08X\teax: %08X\n" "trap: %d\terr: %d\teip: %08X\tcs: %04X\n" "flag: %08X\tSP: %08X\tss: %04X\tcr2: %08X\n", context->gs, context->fs, context->es, context->ds, context->edi, context->esi, context->ebp, context->esp, context->ebx, context->edx, context->ecx, context->eax, context->trapno, context->err, context->eip, context->cs, context->eflags, context->esp_at_signal, context->ss, context->cr2); fflush (stdout); exit (0); }
int main (int argc, char **argv) { struct sigaction sSegvHdl;
sigemptyset (&sSegvHdl.sa_mask); sigaddset (&sSegvHdl.sa_mask, SIGSEGV);
#ifdef SIGACTION sSegvHdl.sa_flags = SA_SIGINFO | SA_ONESHOT; sSegvHdl.sa_sigaction = fSegvHandler; #else sSegvHdl.sa_flags = SA_ONESHOT; sSegvHdl.sa_handler = fSegvHandler; #endif
if (sigaction (SIGSEGV, &sSegvHdl, NULL)) perror ("sigaction"); else *(char *) 0x0 = 0x01; }
-- John
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |