Skip site navigation (1)Skip section navigation (2)
Date:      Wed,  7 Aug 2002 16:22:52 +0200 (CEST)
From:      "Ralf S.Engelschall" <rse@engelschall.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        dev@de.cw.net
Subject:   bin/41410: /bin/sh bug on expanding $? in here-documents
Message-ID:  <20020807142252.6F12B28693@en1.engelschall.com>

next in thread | raw e-mail | index | archive | help

>Number:         41410
>Category:       bin
>Synopsis:       /bin/sh bug on expanding $? in here-documents
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 07 07:30:02 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Ralf S. Engelschall
>Release:        FreeBSD 4.6-STABLE i386
>Organization:
Cavle & Wireless Germany
>Environment:
System: FreeBSD en1.engelschall.com 4.6-STABLE FreeBSD 4.6-STABLE #0: Fri Jul 26 19:25:01 CEST 2002 root@en1.engelschall.com:/v/dsk/0/g/src/sys/compile/EN1 i386

>Description:

While debugging a build problem of GNU Tar 1.3.25 on FreeBSD 4.6-STABLE
for OpenPKG, I discovered a bug in /bin/sh which is triggered by a
construct in Tar's generated GNU Autoconf script "configure". The bug is
that in here-documents the shell-variable $? is expanded incorrectly.
The appended sample script buggy.sh demonstrates the problem. I ran
"uname -a; /bin/sh buggy.sh | grep attempt" on some of our development
machines and it resulted in the following output:

FreeBSD dv1 4.6-STABLE FreeBSD 4.6-STABLE #0: Sun Jul 14 20:58:49 CEST 2002
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=0 $1=foo $2=bar $baz=quux
attempt 3: $?=0 $1=foo $2=bar $baz=quux
FreeBSD dv2 5.0-CURRENT FreeBSD 5.0-CURRENT #0: Sun Jul 28 10:54:41 CEST 2002
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=0 $1=foo $2=bar $baz=quux
attempt 3: $?=0 $1=foo $2=bar $baz=quux
NetBSD dv3 1.6_BETA3 NetBSD 1.6_BETA3 (DV3) #0: Thu Jun 27 19:09:59 UTC 2002
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=0 $1=foo $2=bar $baz=quux
attempt 3: $?=0 $1=foo $2=bar $baz=quux
Linux dv4 2.4.9-21 #1 Thu Jan 17 14:16:30 EST 2002 i686 unknown
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux
Linux dv5 2.2.20 #1 Sat Nov 3 18:25:00 CET 2001 i686 unknown
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux
Linux dv6 2.4.19 #1 SMP Sat Aug 3 15:48:01 CEST 2002 i686 unknown
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux
SunOS dv8 5.8 Generic_108528-15 sun4u sparc SUNW,Ultra-250
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux
SunOS dv9 5.9 Generic sun4u sparc SUNW,Ultra-250
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux
OpenUNIX dv11 5 8.0.0 i386 x86at Caldera UNIX_SVR5
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux

As one can see, the bug is not really FreeBSD specific, because it also
occurs on NetBSD. But all other Unix flavors I tested consistently show
the expected result (three times the value 1). The same happens with GNU
Bash on all platforms (every time the correct value 1). So I have to
assume that the output of /bin/sh on FreeBSD and NetBSD is incorrect and
caused by a bug.

=====================================================================
#!/bin/sh -x
#  buggy.sh

set -- foo bar
baz=quux

#   attempt #1 (simple echo for comparison)
test yes != yes
echo "attempt 1: \$?=$? \$1=$1 \$2=$2 \$baz=$baz"

#   attempt #2 (small here-document)
test yes != yes
cat <<EOF
attempt 2: \$?=$? \$1=$1 \$2=$2 \$baz=$baz
EOF

#   attempt #3 (large here-document >= 4KB)
test yes != yes
cat <<EOF
attempt 3: \$?=$? \$1=$1 \$2=$2 \$baz=$baz
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
EOF
=====================================================================

>How-To-Repeat:

$ /bin/sh
$ (exit 42)
$ echo "$?" 
42
$ (exit 42)   
$ cat <<EOF
> $?
> EOF
0
$ _

>Fix:

I already poked around in the source of /bin/sh in HEAD and RELENG_4, but
was not able to really discover or even solve the bug. I only discovered
that the source of the failure in "attempt 2" seems to be caused by
an assignment of the exit value in eval.c:

Index: eval.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/eval.c,v
retrieving revision 1.27.2.4
diff -u -d -r1.27.2.4 eval.c
--- eval.c      19 Jul 2002 04:38:51 -0000      1.27.2.4
+++ eval.c      7 Aug 2002 14:09:07 -0000
@@ -442,7 +442,9 @@
        for (redir = n ; redir ; redir = redir->nfile.next) {
                struct arglist fn;
                fn.lastp = &fn.list;
+#if 0
                oexitstatus = exitstatus;
+#endif
                switch (redir->type) {
                case NFROM:
                case NTO:

With this test-removal I get at least "attempt 2: $?=1 $1=foo $2=bar
$baz=quux". But perhaps now something else is broken, of course. So we
really need someone with more knowledge of the /bin/sh internals to dive
into the source and fix it for us.

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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