Signal Handler Launch

   

The function in the kernel that arranges for the signal handler to be called is sendsig(). Its job is to set up the stack frames for the call to the user function. It also has to make sure that when the routine finishes, it returns to the right place to clean up the signal data structures. It calls a variety of utility routines to do the work it has to do.

The first is sendsig_alloc_sigcontext(), which allocates space on the stack to hold the sigcontext structure. This space be can either on the user's stack or on a separate signal stack depending on the flags for this signal. Data is copied into this sigcontext structure by sendsig_fillin_slm(), sendsig_copyoutsavestate(), and sendsig_fillin_xsi().

The stack frame used for calling the user's function is set up such that the return address points to the sigcleanup() routine. More specifically, since the signal handler is going to be in user space and sigcleanup() is a kernel routine, the return address points to a stub in libc that handles the callback into the kernel for cleanup.

We also have to manipulate things to actually get into the signal handler. Remember that we're in the kernel code, and we got here by means of a trap, a sleep, a wakeup, or a system call. Those are the things that cause signal detection. We have a save state, which points back to the user code that sent us into the kernel. (For details on this, see Chapter 4.) We have to modify that save state so that when we leave kernel mode, we go instead to the user's handler. sendsig_setuphandler() does this by modifying the value of GR 31 the return pointer in the save state.

sendsig() has sanity checks throughout this process to make sure the user's stack hasn't been corrupted. If any utility routine fails because it's unable to manipulate the user's stack, the process gets immediately terminated. This is done by one of my favorite routines sendsig_the_barbarian(). Even kernel engineers have a sense of humor.

Signal Handler Return

When the user's signal handler returns, it branches back to the return pointer it was given by sendsig(). This vectors into a routine in libc, which then goes to a system call to the sigcleanup() kernel routine. sigcleanup() has a pretty easy job it essentially restores the save state that was saved by sendsig() so that when it returns, it will go back to the place the signal occurred. There are some sanity checks to make sure the user hasn't modified the stack in any way he or she shouldn't have, and once again sendsig_the_barbarian() is there to cut down any process with an invalid stack.



HP-UX 11i Internals
HP-UX 11i Internals
ISBN: 0130328618
EAN: 2147483647
Year: 2006
Pages: 167

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net