Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <3D4F758C.4010109@colorfullife.com> Date: Tue, 06 Aug 2002 09:06:52 +0200 From: Manfred Spraul User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.0) Gecko/20020530 X-Accept-Language: en-us, en MIME-Version: 1.0 To: cygwin AT cygwin DOT com, bug-bash AT gnu DOT org Subject: [PATCH] cygwin+bash: bash reorders script output bug identified/fixed Content-Type: multipart/mixed; boundary="------------070407050708010501050600" --------------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--