Mail Archives: cygwin/2002/08/06/03:08:24
--------------070407050708010501050600
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Hi,
I've figured out why bash reorders output from my shell script. I've
attached a new, simpler script to reproduce the bug
Just run
./w.sh
If it fails, then lines in output.txt are reordered
(i.e. script output something).
Please retry a few times, it's not 100% reproducable.
Summary:
* It's a bash bug, not a cygwin bug.
* defining RECYCLES_PIDS in execute_cmd.c solves the problem.
* RECYCLES_PID is intended for LynxOs, which recycles pids
quickly according to a comment in execute_cmd.c
* All OS are potentially affected, bash basically assumes
that 2 pid values are never identical.
It seems that there are 2 possible solutions:
A) enable RECYCLES_PID in bash.
* I'd propose that, minimal patch attached.
B) work around the bash bug in cygwin.
fork.cc already contains a special function that prevents 2
consecutive fork() calls from reusing the same pid:
slow_pid_reuse().
But it doesn't work in this context:
When bash executes a command, it sometimes creates a subprocess.
make_child saves the new pid in a global variable (last_made_pid).
execute_command_internal() calls execute_simple_command() and checks
if last_made_pid has changed during the call. If last_made_pid has not
changed (command was a builtin, handled without fork()), then wait_for()
is not called by execute_command_internal(), to prevent bash from
hanging.
I.e. if the same pid is used for 2 consecutive command subprocesses,
bash fails, because it thinks the command was a builtin and doesn't wait
until the external process exits.
My probem is caused by process_substitute: The function handles command
substitution, and that function saves & restores last_made_pid.
Thus the same pid value must not be used for 2 consecutive _command_
subprocesses, which is different from 2 consecutive fork() calls.
I don't see how fork.cc could work around that bash bug. I'd propose the
attached patch, that enables RECYCLES_PIDS for cygwin.
Note: I've manually edited both configure.in and configure, because I
don't have autoconf installed. Please test before applying the patch.
Obviously I'd prefer if RECYCLES_PIDS is unconditionally enabled in
all OS.
--
Manfred
<<<<<< bugbash output:
Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: cygwin
Compiler: i686-pc-cygwin-gcc
Compilation CFLAGS: -DPROGRAM='bash.exe' -DCONF_HOSTTYPE='i686'
-DCONF_OSTYPE='cygwin' -DCONF_MACHTYPE='i686-pc-cygwin'
-DCONF_VENDOR='pc' -DSHELL -DHAVE_CONFIG_H -I. -I../bash-2.05b
-I../bash-2.05b/include -I../bash-2.05b/lib -g -O2
uname output: CYGWIN_NT-5.0 AB 1.3.12(0.54/3/2) 2002-07-03 16:42 i686
unknown
Machine Type: i686-pc-cygwin
Bash Version: 2.05b
Patch Level: 0
Release Status: release
<<<<<<<
cygwin version: 1.3.12-1
<<<<<<<
--------------070407050708010501050600
Content-Type: text/plain;
name="w.sh"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="w.sh"
#!/bin/bash
# the comments explain what's needed to trigger the bug
#
fnc() {
# e.g. process id 1000
n=1
while [ $n -lt 50 ];do
n=$[$n+1]
rm -f m-$n.txt
# subprocess created for rm.
# process id 1001, saved in last_made_pid.
echo "YYY $n" > lfile.txt
echo "W $n"
for i in 0 1 2 3 4 5 6 7 8 9 10;do
mu=`echo $n $i | gawk '{printf("%f\n",$1+$2);}'`
# several subprocesses created by
# process_substitute.
# consecutive pid values are never identical,
# bug process_substitute always restores
# last_made_pid to 1001.
echo "$mu" >> m-$n.txt
done
echo "XX $n"
cat lfile.txt
# subprocess created, pid 1001.
# result: execute_command_internal thinks that it's
# a builtin and doesn't wait until cat exits.
echo "ZZZZ $n"
# echo prints "ZZZZ $n"
# now cat runs, and outputs YYY --> YYY after ZZZZ
rm -f m-$n.txt
done
}
rm -f m-*.txt
fnc > output.txt
rm lfile.txt
#
# now check if the output file is correct
#
gawk ' {i++} /W/{if (i%4 != 1) printf("%s\n",$0);} /X/{if (i%4 != 2) printf("%s\n",$0);} /Y/{if (i%4 != 3) printf("%s\n",$0);} /Z/{if (i%4 != 0) printf("%s\n",$0);}' < output.txt
--------------070407050708010501050600
Content-Type: application/x-java-applet;
name="patch-bash"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename="patch-bash"
LS0tIGJhc2gtMi4wNWItMi9jb25maWd1cmUuaW4JMjAwMi0wOC0wNSAyMjo0ODo0OC4wMDAw
MDAwMDAgKzAyMDAKKysrIGJhc2gtMi4wNWItMi5vcmlnL2NvbmZpZ3VyZS5pbgkyMDAyLTA3
LTE2IDE1OjMxOjI2LjAwMDAwMDAwMCArMDIwMApAQCAtODUxLDcgKzg1MSw3IEBACiBsaW51
eCopCQlMT0NBTF9MREZMQUdTPS1yZHluYW1pYyA7OwkgIyBhbGxvdyBkeW5hbWljIGxvYWRp
bmcKICpxbngqKQkJTE9DQUxfQ0ZMQUdTPSItRHFueCAtRiAtM3MiIExPQ0FMX0xERkxBR1M9
Ii0zcyIgTE9DQUxfTElCUz0iLWx1bml4IC1sbmN1cnNlcyIgOzsKIHBvd2VydXgqKQlMT0NB
TF9MSUJTPSItbGdlbiIgOzsKLWN5Z3dpbiopCUxPQ0FMX0xJQlM9Ii1sdXNlcjMyIjsgTE9D
QUxfQ0ZMQUdTPS1EUkVDWUNMRVNfUElEUyA7OworY3lnd2luKikJTE9DQUxfTElCUz0iLWx1
c2VyMzIiIDs7CiBvcGVubnQqfGludGVyaXgqKSBMT0NBTF9DRkxBR1M9Ii1ETk9fTUFJTl9F
TlZfQVJHIC1EQlJPS0VOX0RJUkVOVF9EX0lOTyIgOzsKIGVzYWMKIAotLS0gYmFzaC0yLjA1
Yi0yL2NvbmZpZ3VyZQkyMDAyLTA4LTA1IDIyOjQ3OjUyLjAwMDAwMDAwMCArMDIwMAorKysg
YmFzaC0yLjA1Yi0yLm9yaWcvY29uZmlndXJlCTIwMDItMDctMTYgMTU6MzE6NDguMDAwMDAw
MDAwICswMjAwCkBAIC0xNTM0Niw3ICsxNTM0Niw3IEBACiBsaW51eCopCQlMT0NBTF9MREZM
QUdTPS1yZHluYW1pYyA7OwkgIyBhbGxvdyBkeW5hbWljIGxvYWRpbmcKICpxbngqKQkJTE9D
QUxfQ0ZMQUdTPSItRHFueCAtRiAtM3MiIExPQ0FMX0xERkxBR1M9Ii0zcyIgTE9DQUxfTElC
Uz0iLWx1bml4IC1sbmN1cnNlcyIgOzsKIHBvd2VydXgqKQlMT0NBTF9MSUJTPSItbGdlbiIg
OzsKLWN5Z3dpbiopCUxPQ0FMX0xJQlM9Ii1sdXNlcjMyIjsgTE9DQUxfQ0ZMQUdTPS1EUkVD
WUNMRVNfUElEUyA7OworY3lnd2luKikJTE9DQUxfTElCUz0iLWx1c2VyMzIiIDs7CiBvcGVu
bnQqfGludGVyaXgqKSBMT0NBTF9DRkxBR1M9Ii1ETk9fTUFJTl9FTlZfQVJHIC1EQlJPS0VO
X0RJUkVOVF9EX0lOTyIgOzsKIGVzYWMKIAo=
--------------070407050708010501050600
Content-Type: text/plain; charset=us-ascii
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
--------------070407050708010501050600--
- Raw text -