[comp.unix.questions] Problem with sigvector

jad@insyte.UUCP (10/27/87)

We are running C on HP-UX version 5.11 on a HP9000/9050.

The problem is that I have a signal handler for SIGSEGV which sometimes
causes a segmentation fault of its own and this causes the system to
hang.  This happens using sigvector (I haven't tried it with signal).
(Now I know that it is bad practice for a signal handler to fault but
I have no real choice.  See below)  I want to know what is really happening.
My theory is that the signal handler is waiting for itself to finish.
Normally when a signal occurs, control passes to the signal handler which
either exits the program or returns to where the program left off.  In this
case the signal handler causes a signal and then waits for
control to return.  Unfortunately the signal cannot get to the signal handler
because it is already busy!  (HP-UX sigvector blocks the specific signal
its processing before entering the signal handler.)  Based on this theory
I tried to set SIGSEGV to ignore upon entering the signal handler.  This
had no effect, the system still hung.  I've reported this problem to the
HP Response Center and they seem to think that there is a bug somewhere.
I would like: 1) an explaination of whats going on. 2) to know if the 
included test program hangs on other systems too. 3) to find a go around
if its a bug or a solution if its not.

The reason that my signal handler sometimes causes a segmentation fault 
is that the application uses CURSES and I need to at least try to reset
the terminal on an error exit.  CURSES resets the terminal (and 
just about everything else it can get its hands on) so I have set up
a signal handler to catch most signals inorder to try to restore the 
terminal to its original setting before exiting.
This works fine for most signals.  It doesn't work well for the 
SIGSEGV signal.  Most of the Segmentation faults that I've seen come
from a bug in our code which messes up CURSES.  About 90% of the time,
we will get a segmentation fault, drop into the signal handler which 
will successfully call CURSES to reset the terminal and then it will
exit.  But, about 10% of the time, CURSES is so messed up that trying
to reset the terminal causes another segmentation fault.  This is the
situation I've described above.

Sample program which hangs the system:

#include <stdio.h>
#include <signal.h>

/*****  Routine to cause a segmentation fault *****/
int causeSegV ()
{
  int *pp;
  int xx,  p = 0;

  pp = (int *)p;
  xx = *pp;
}

/***** Segmentation Fault Signal Handler *****/
int signalHandler (sig, code, scp)
int sig, code;
struct sigcontext *scp;
{
  struct sigvec vec;

  printf ("In signalhandler,  signal=%d\n", sig);

    /*  This doesn't help the problem at all - it has no noticable effect */
    /*****  try setting SIGSEGV to ignore *****/
    vec.sv_handler = SIG_IGN;
    vec.sv_mask = 0;
    sigvector (SIGSEGV, &vec, (struct sigvec *)0);

  causeSegV ();

  printf ("Exiting signalHandler,  signal =%d\n", sig);
}

/*****  MAIN Program  *****/
main ()
{
  struct sigvec vec;


  /*****  Set SIGSEGV ******/
  vec.sv_handler = signalHandler;
  vec.sv_mask = ~(unsigned long)0;
  sigvector (SIGSEGV, &vec, (struct sigvec *)0);

  /*****  Print message *****/
  printf ("Hello- right before segmentation fault\n");

  /*****  Cause a segmentation fault *****/
  causeSegV ();

  exit(0);
}