From owner-freebsd-bugs@FreeBSD.ORG Thu Oct 27 16:20:08 2011 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 25B6F106564A for ; Thu, 27 Oct 2011 16:20:08 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id F2AA68FC12 for ; Thu, 27 Oct 2011 16:20:07 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id p9RGK7Al039714 for ; Thu, 27 Oct 2011 16:20:07 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id p9RGK7Uk039713; Thu, 27 Oct 2011 16:20:07 GMT (envelope-from gnats) Resent-Date: Thu, 27 Oct 2011 16:20:07 GMT Resent-Message-Id: <201110271620.p9RGK7Uk039713@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Fabian Keil Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DF25E106566B for ; Thu, 27 Oct 2011 16:16:28 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22]) by mx1.freebsd.org (Postfix) with ESMTP id C4D3D8FC1A for ; Thu, 27 Oct 2011 16:16:28 +0000 (UTC) Received: from red.freebsd.org (localhost [127.0.0.1]) by red.freebsd.org (8.14.4/8.14.4) with ESMTP id p9RGGS6B061424 for ; Thu, 27 Oct 2011 16:16:28 GMT (envelope-from nobody@red.freebsd.org) Received: (from nobody@localhost) by red.freebsd.org (8.14.4/8.14.4/Submit) id p9RGGS61061423; Thu, 27 Oct 2011 16:16:28 GMT (envelope-from nobody) Message-Id: <201110271616.p9RGGS61061423@red.freebsd.org> Date: Thu, 27 Oct 2011 16:16:28 GMT From: Fabian Keil To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: bin/162064: Loop in fetch when sending SIGINFO after the server stopped sending data X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Oct 2011 16:20:08 -0000 >Number: 162064 >Category: bin >Synopsis: Loop in fetch when sending SIGINFO after the server stopped sending data >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Oct 27 16:20:07 UTC 2011 >Closed-Date: >Last-Modified: >Originator: Fabian Keil >Release: HEAD >Organization: >Environment: FreeBSD r500.local 10.0-CURRENT FreeBSD 10.0-CURRENT #370 r+e5cde8a: Tue Oct 25 21:12:37 CEST 2011 fk@r500.local:/usr/obj/usr/src/sys/ZOEY amd64 >Description: If fetch receives SIGINFO after the server stopped sending data it goes into a loop and starts eating 100% cpu even continuing after the connection to the server has been closed. It's my impression that fetch.c relies on fread() to modify errno in a way it doesn't. The following patch prevents the cpu-eating loop, but fetch still fails to properly save the received data: commit 2131ebe654b5d9b48a715ea1955941b9d3e89f4d Author: Fabian Keil Date: Sat Oct 15 22:12:54 2011 +0200 Manually set errno to 0 before calling fread() in fetch(). The fact that this makes a difference seems to suggest that fread() doesn't behave like fetch expects it to. diff --git a/usr.bin/fetch/fetch.c b/usr.bin/fetch/fetch.c index 9862276..18c6d5a 100644 --- a/usr.bin/fetch/fetch.c +++ b/usr.bin/fetch/fetch.c @@ -636,6 +636,7 @@ fetch(char *URL, const char *path) stat_end(&xs); siginfo = 0; } + errno = 0; /* XXX: Why does this have an effect? */ if ((size = fread(buf, 1, size, f)) == 0) { if (ferror(f) && errno == EINTR && !sigint) clearerr(f); >How-To-Repeat: Run a "webserver" like this one: (printf "HTTP/1.1 200 Okay\r\nConnection: close\r\nContent-Length: 10\r\n\r\n0123456789"; sleep 5) | nc -l 81 Use fetch to request a resource, send SIGINFO before the sleep time is up and watch it eating cpu time without doing anything useful: fk@r500 ~ $fetch http://127.0.0.1:81/ fetch.out 0% of 10 B 0 Bps load: 0.80 cmd: fetch 3698 [select] 0.70r 0.00u 0.00s 0% 2464k fetch.out 0% of 10 B 0 Bps fetch.out 0% of 10 B 0 Bps load: 0.83 cmd: fetch 3698 [runnable] 12.32r 0.64u 10.96s 70% 2504k fetch.out 0% of 10 B 0 Bps fetch.out 0% of 10 B 0 Bps load: 0.87 cmd: fetch 3698 [running] 24.50r 1.22u 22.54s 96% 2504k fetch.out 0% of 10 B 0 Bps fetch.out 0% of 10 B 0 Bps load: 0.91 cmd: fetch 3698 [running] 52.70r 2.84u 49.10s 100% 2504k fetch.out 0% of 10 B 0 Bps fetch.out 0% of 10 B 0 Bps load: 0.92 cmd: fetch 3698 [running] 59.60r 3.26u 55.55s 100% 2504k fetch.out 0% of 10 B 0 Bps fetch.out 0% of 10 B 0 Bps^C fetch: transfer interrupted With the errno patch one gets: fk@r500 /tank/scratch $fetch http://127.0.0.1:81/ fetch.out 0% of 10 B 0 Bps load: 0.74 cmd: fetch 3812 [select] 0.69r 0.00u 0.00s 0% 2464k fetch.out 0% of 10 B 0 Bps fetch.out 0% of 10 B 0 Bps fetch: http://127.0.0.1:81/: No error: 0 and no output file even though all the data has been delivered. If SIGINFO isn't sent, the resource is properly received. >Fix: >Release-Note: >Audit-Trail: >Unformatted: