[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Log for attempted build of gzip_1.6-1 on m68k (dist=unstable)

On 06/19/2013 07:18 AM, Antonio Diaz Diaz wrote:
> Thorsten Glaser wrote:
>> what do I do to investigate this:
>> zgrep-signal: set-up failure: signal handling busted on this host
>> ERROR: zgrep-signal
> FWIW, I have found this same bug on an i686 machine, with gzip 1.5 and 1.6, but never found the cause. (My shell is bash).

Thanks for confirming it.  This prompted me to look at the code again
(my! I haven't used Perl in a year and a half! time to brush off
some of that rust...) and I found a race condition that could explain
the bug.  I pushed the following patch; can you please give it a try?
(Hmm, I now see a typo "becausee" in a comment; I'll fix that.)

>From 4c0bc4089a762ffef20ad9e0311e634e44b4cfdd Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Wed, 19 Jun 2013 08:46:29 -0700
Subject: [PATCH] tests: zgrep-signal race condition fix

* tests/zgrep-signal: Check that Perl supports dup2.
(exec_with_SIGPIPE_SIGDFL): Remove.
(write_to_dangling_pipe): Simplify by moving more of it into Perl.
Fix race condition, where subcommand writes to a pipe before the ":"
command exits.  Problem reported by Thorsten Glaser in
 tests/zgrep-signal | 38 +++++++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/tests/zgrep-signal b/tests/zgrep-signal
index 3a9c089..5475e5e 100755
--- a/tests/zgrep-signal
+++ b/tests/zgrep-signal
@@ -23,34 +23,42 @@
 echo a | gzip -c > f.gz || framework_failure_
 test "x$PERL" = x && PERL=perl
-("$PERL" -e 'use warnings') >/dev/null 2>&1 || skip_ "no suitable perl found"
+("$PERL" -e 'use POSIX qw(dup2)') >/dev/null 2>&1 ||
+   skip_ "no suitable perl found"
-exec_with_SIGPIPE_SIG_DFL () {
+# Run the arguments as a command, in a process where stdout is a
+# dangling pipe and SIGPIPE has the default signal-handling action.
+# This can't be done portably in the shell, becausee if SIGPIPE is
+# ignored when the shell is entered, the shell might refuse to trap
+# it.  Fall back on Perl+POSIX, if available.  Take care to close the
+# pipe's read end before running the program; the equivalent of the
+# shell's "command | :" has a race condition in that COMMAND could
+# write before ":" exits.
+write_to_dangling_pipe () {
   for arg; do
     args="$args, '$arg'"
-  "$PERL" -e "\$SIG{PIPE} = 'DEFAULT'; exec '$program'$args"
+  "$PERL" -e '
+     use POSIX qw(dup2);
+     $SIG{PIPE} = "DEFAULT";
+     pipe my ($read_end, $write_end) or die "pipe: $!\n";
+     dup2 fileno $write_end, 1 or die "dup2: $!\n";
+     close $read_end or die "close: $!\n";
+     exec '"'$program'$args"';
+  '
-write_to_dangling_pipe () {
-  exec 3>&1
-  (
-    exec_with_SIGPIPE_SIG_DFL "$@"
-    echo $? >&3
-  ) | : || framework_failure_
-signal_status=$(write_to_dangling_pipe cat f.gz f.gz)
+write_to_dangling_pipe cat f.gz f.gz
 test 128 -lt $signal_status ||
   framework_failure_ 'signal handling busted on this host'
-st=$(write_to_dangling_pipe zgrep a f.gz f.gz)
-test $st = $signal_status || fail=1
+write_to_dangling_pipe zgrep a f.gz f.gz
+test $? -eq $signal_status || fail=1
 Exit $fail

Reply to: