$ ping cban PING cban.cban.com (204.209.160.1): 56 data bytes ^C^C^C^C^C^C^C [... and it doesn't exit...] The namesever for the above host is not reachable right now, so trying to do the reverse lookup hangs for a long period of time. The problem is that ^C won't exit. This is because the SIGINT signal handler just sets a flag telling ping to exit. That doesn't do anything because ping in a select() in res_send which is retried if it gets an EINTR. 0x80873b1 in select () (gdb) up #1 0x806b5a0 in res_send () (gdb) up #2 0x8067eaa in res_query () (gdb) up #3 0x8063786 in _gethostbydnsaddr () (gdb) up #4 0x8062156 in gethostbyaddr () (gdb) up #5 0x361e in pr_addr (ina={s_addr = 1772147148}) at ping.c:1168 1168 if ((options & F_NUMERIC) || (gdb) This problem was introduced in revision 1.22 of ping.c. Fix: Perhaps do a setjmp somewhere then have the signal handler do a longjmp out and have it check the flag then. Lowering the _res timeouts for the resolver would help a little, but isn't really a good solution because it would still hang for a bit and because it would result in false negatives for reverses for a small number of hosts. How-To-Repeat: Find a host where all the nameservers are unreachable for the reverse lookup. ping it.
Responsible Changed From-To: gnats-admin->freebsd-bugs Misfiled PR.
State Changed From-To: open->closed Fixed by sef in r1.24 of ping.c on 1997/07/13
On Mon, 4 Sep 2000 kris@FreeBSD.ORG wrote: > Synopsis: ping hangs on certain unresolvable hosts > > State-Changed-From-To: open->closed > State-Changed-By: kris > State-Changed-When: Mon Sep 4 15:21:48 PDT 2000 > State-Changed-Why: > Fixed by sef in r1.24 of ping.c on 1997/07/13 No, this was only fixed for some values of "certain", and not the ones described in the PR. Rev.1.24 of ping.c mainly makes all syscalls return EINTR when they are interrupted by a SIGINT or SIGALRM. This fixes hangs in sendto() and/or recvmsg(), but has no effect on the hangs described in the PR since those involve select() and select() always returns EINTR when it is interrupted. As described in the PR, res_send() retries almost endlessly after select() returns EINTR. I think this is a bug in res_send(). It can't be aborted by non-broken signal handlers except by ones that do little more than call _exit(2). ping used to have broken signal handlers that did lots of unsafe cleanups before exiting unsafely by calling exit(3). PR 20613 is about essentially the same bug for "fetch -T n". The timeout doesn't work when the SIGALRM occurs in res_send(), since res_send() just retries after select() returns EINTR. Bruce
State Changed From-To: closed->open Closed in error.
State Changed From-To: open->patched A partial workaround has been committed in revision 1.102 of ping.c. This just allows you to exit ping by hitting ^C a second time in the case where it is waiting for gethostbyaddr() to complete.
State Changed From-To: patched->closed Patch MFC'd to -STABLE now.