Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Mar 2005 03:50:19 GMT
From:      Bruce Evans <bde@zeta.org.au>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/78304: Signal handler abuse in comsat(8)
Message-ID:  <200503030350.j233oJ6i070594@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/78304; it has been noted by GNATS.

From: Bruce Evans <bde@zeta.org.au>
To: Gavin Atkinson <gavin.atkinson@ury.york.ac.uk>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: bin/78304: Signal handler abuse in comsat(8)
Date: Thu, 3 Mar 2005 14:41:52 +1100 (EST)

 On Wed, 2 Mar 2005, Gavin Atkinson wrote:
 
 >> Description:
 >
 > 	I've been inspired by the talk given by Henning Brauer given at
 > the UKUUG Winter 2005 on writing safe signal handlers, and have set about
 > fixing some of them in the FreeBSD source tree.
 
 In case you fix lots of these...
 
 > while the main routine is already in the memory allocator.  This latter
 > signal has been fixed to simply set a flag, which is now polled and acted
 > upon in the main loop.
 
 ... note that simply setting a flag is usually simply wrong, since FreeBSD
 has restartable syscalls, restarting syscalls after a signal is the
 default for signal(2), and most applications and libraries don't handle
 changing the default using siginterrupt(3) or not setting the default
 using sigaction(2) (!SA_RESTART).  Restarting syscalls can result in the
 poll in the main loop never being reached, since a syscall can wait forever.
 
 Examples of utilities whose signal handling bugs have been moved by simply
 setting a flag:
 
 - ping(8).  ping's fixes are not so simple but don't quite work.  The
    resolver library sometimes hangs, and SIGINT to abort ping doesn't work
    because the resolver library restarts.  In this case, the relevant
    syscall is select() or kevent() so it isn't automatically restarted,
    and callers of these syscalls must actually do something about EINTR,
    but the resolver library doesn't know what to do and always restarts.
 
 - top(1).  top was changed to simply set a flag.  It now hangs in a
    read() from a terminal in some contexts.  It then appears to ignore
    SIGINT, but when you enter something the read completes, control
    returns to the level that polls the flag, and the SIGINT actually
    terminates the program.
 
 Fixing this in large programs is hard, but comsat seems to be simple
 enough to fix or to verify that there is no problem.  Fixing a large
 program seems to require never using automatic restarts for syscalls
 and then fixing all the bugs exposed by this, perhaps starting with
 the one in stdio (there is a PR about at least 1).
 
 Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200503030350.j233oJ6i070594>