Vaclav Haisman wrote:
> > If you want this to not happen, you should explicitly uninstall the
> > handler, or you should call abort(3) (or _exit(2), if you don't want
> > to leave a core dump).
> 
> Even though this is probably about my misunderstanding of things I post here
> the test I used.

[ ... ]

> void handler (int, siginfo_t * info, ucontext_t * uap)
> {
>   std::cerr << "SIGSEGV has been caught" << std::endl;
>   struct sigaction mysig;
>   mysig.sa_handler = SIG_DFL;
>   mysig.sa_sigaction = NULL;
>   mysig.sa_flags = 0;
>   if (sigaction(SIGSEGV, &mysig, NULL) == -1)
>     {
>       std::cerr << "Error in sigaction()" << std::endl;
>       abort();
>     }
> 
>   f((int*)NULL);

This is not legal.

>   /*mysig.sa_handler = SIG_DFL;

[ ... commented out handler reset code ... ]

I don't understand why you do this.


Performing a NULL pointer dereference in a signal handler for a
signal which is generated by a NULL pointer dereference is not
really a good idea.  The signal handler, once entered, masks the
signal.  It's possible that the signal handler itself is reset
on exit (this is implementation defined).

The main problem here is that signals are not events, they are
persistent conditions.  FreeBSD does not support POSIX queued
signals, at this time, so it's not possible to treat them as
events under any circumstances.

Though there may be issues with stack unwinding, with C++, I
don't think that's your problem.  You could try implementing the
same program in C, and determine if it has the same symptoms.

You may also try adding:

        memset( &mysig, 0, sizeof(struct sigaction));

after the declaration, but prior to your use of the stack
variable.  Specifically, I do not see you setting the sa_mask
structure member anywhere, and that could be Bad(tm), particularly
if you were setting masking on the signal that triggered the call,
and then re-triggering it.  It's conceivable that the implementation
would check the sa_mask before resetting the handler.


Also, note that any use of functions not in this list:

     Base Interfaces

      exit() access() alarm() cfgetispeed() cfgetospeed() cfsetispeed()
      cfsetospeed() chdir() chmod() chown() close()
      creat() dup() dup2() execle() execve() fcntl() fork() fpathconf()
      fstat() fsync() getegid() geteuid() getgid() getgroups() getpgrp()
      getpid() getppid() getuid() kill() link() lseek() mkdir() mkfifo()
      open() pathconf() pause() pipe() raise() read() rename() rmdir()
      setgid() setpgid() setsid() setuid() sigaction() sigaddset()
      sigdelset() sigemptyset() sigfillset () sigismember() signal()
      sigpending() sigprocmask() sigsuspend() sleep() stat() sysconf()
      tcdrain() tcflow() tcflush() tcgetattr() tcgetpgrp() tcsendbreak()
      tcsetattr() tcsetpgrp() time() times() umask() uname()
      unlink() utime() wait() waitpid() write() 

     Realtime Interfaces

      aio_error() clock_gettime() sigpause() timer_getoverrun() 
      aio_return() fdatasync() sigqueue() timer_gettime() 
      aio_suspend() sem_post() sigset() timer_settime() 

are specifically considered "unsafe" by POSIX, and their behaviour is
undefined.  Specifically:

        All functions not in the above table are considered to be
        unsafe with respect to signals. In the presence of signals,
        all functions defined by this specification will behave as 
        defined when called from or interrupted by a signal-catching
        function, with a single exception: when a signal interrupts
        an unsafe function and the signal-catching function calls an
        unsafe function, the behaviour is undefined. 

I'd say that was exactly the case you were testing with the function
"f", and by using "cout" to do I/O in the handler.

-- Terry

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to