Signal handling: what you can't do.
Werner Koch
wk at gnupg.org
Mon Aug 30 18:20:22 CEST 1999
Hi Geoff,
First, many thanks for your review. I still have some questions:
Geoff Keating <geoffk at ozemail.com.au> writes:
> static RETSIGTYPE
> got_fatal_signal( int sig )
> {
> if( caught_fatal_sig )
> raise( sig );
> caught_fatal_sig = 1;
>
> fprintf( stderr, "\n%s: %s caught ... exiting\n",
> log_get_name(), signal_name(sig) );
> secmem_term();
> exit( 8 );
> }
>
> now, this is not good. There are three issues here, but most flow
> from the same important rule:
>
> In a signal handler, under Linux (and most other unixes), you cannot:
>
> 1. Assume that the values in non-volatile variables are stored in the same
> order as implied by the code (or in fact, that they are ever stored
> at all);
But caught_fatal_sig is declared volatile; so where is the problem
here?
> 2. Call non-reentrant procedures.
I know that using printf is not good style but the only problem I can
see, is that the output is garbled or you get an SEGV.
I tried to use write(2) directly here but for some reasons
(portability?) I gave up on this. I assume that the correct solution
would be to register an atexit function which displays such a message
if a fatal signal occured.
> Also for instance, in secmem_init, there is this code:
>
> else {
> pool_is_mmapped = 1;
> pool_okay = 1;
> }
>
> there is absolutely no guarantee that `pool_is_mmapped' is physically
> set to 1 before `pool_ok', or that `pool_ok' is set to 1 after the
Okay. I make pool_okay volatile.
> Finally, a minor nit: in signal_name(), there is this:
>
> #if SYS_SIGLIST_DECLARED
> return sys_siglist[signum];
> #else
> static char buf[20];
> sprintf(buf, "signal %d", signum );
> return buf;
> #endif
>
> it should check that `signum' is less than NSIG, or better yet it
> should use strsignal() which does the check for you and will still
Which is not available on BSD systems
> Again on my system this won't happen because NSIG is greater than the
> signal number of all the signals for which signal_name is actually
> called; but it's not robust code.
Okay, add a bounds check.
--
Werner Koch at guug.de www.gnupg.org keyid 621CC013
More information about the Gnupg-devel
mailing list