From owner-freebsd-bugs@FreeBSD.ORG Sun Feb 8 07:39:06 2004 Return-Path: Delivered-To: freebsd-bugs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C806616A4CE; Sun, 8 Feb 2004 07:39:06 -0800 (PST) Received: from mailout2.pacific.net.au (mailout2.pacific.net.au [61.8.0.85]) by mx1.FreeBSD.org (Postfix) with ESMTP id 51D6443D1D; Sun, 8 Feb 2004 07:39:06 -0800 (PST) (envelope-from bde@zeta.org.au) Received: from mailproxy2.pacific.net.au (mailproxy2.pacific.net.au [61.8.0.87])i18Fd55O021201; Mon, 9 Feb 2004 02:39:05 +1100 Received: from gamplex.bde.org (katana.zip.com.au [61.8.7.246]) i18Fd3Yc016066; Mon, 9 Feb 2004 02:39:03 +1100 Date: Mon, 9 Feb 2004 02:39:02 +1100 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: "Jukka A. Ukkonen" In-Reply-To: <200402081121.i18BLwEl037903@www.freebsd.org> Message-ID: <20040209021755.P44973@gamplex.bde.org> References: <200402081121.i18BLwEl037903@www.freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: freebsd-bugs@freebsd.org cc: freebsd-gnats-submit@freebsd.org Subject: Re: kern/62524: SIGALRM is not delivered when res_send() hangs waiting in kevent() X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 08 Feb 2004 15:39:06 -0000 On Sun, 8 Feb 2004, Jukka A. Ukkonen wrote: > >Description: > When an interval timer should trigger a SIGALRM delivery to > a process which tries to resolve an address to an FQDN and > there is no name service available for the corresponding > in-addr.arpa. domain the signal is not delivered. > > Instead the process simply hangs waiting in ... > > #0 0x280b3c00 in kevent () from /usr/lib/libc.so.4 > #1 0x280c63f5 in res_send () from /usr/lib/libc.so.4 > #2 0x280c9799 in res_query () from /usr/lib/libc.so.4 > #3 0x280d5ccf in _gethostbydnsaddr () from /usr/lib/libc.so.4 > #4 0x280d45f0 in gethostbyaddr () from /usr/lib/libc.so.4 > > The process continues only when the resolver timeout expires. > > This is a disaster for any program which uses setitimer() and > SIGALRM to drive periodic tasks at regular intervals. > > It looks like kevent() is not properly interrupted by the signal. Are you sure that it doesn't get delivered? There is an old bug in the resolver library that causes it to wait forever. The signal gets delivered and (at least using select() instead of kevent()) the resolver sees EINTR, but the resolver retries forever in some cases. This breakes signal handling in ping(8). The signal is delivered to ping but ping just sets a flag and waits for its main loop to be returned to to check the flag, but the resolver never returns. BTW, correct signal handlers that just set a flag often don't actually work. E.g., top's signal handling was broken years ago by changing its hanflers to just set a flag. The SIGINT handler is attached using signal(), so most syscalls don't return after a signal and top can't be killed by ^C when it is in such a syscall -- e.g., start top and type "s"; top then waits for input and if you type ^C then it keeps waiting for input and the ^C is not acted on until you type some input (or kill the program using an uncaught signal). Signal handlers must be installed without SA_RESTART for the just-set-a-flag method to work, and then everything that does i/o, including stdio calls, needs to be SYSVified to expect EINTR. Few programs or libraries get this right. Bruce