www.delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2002/08/06/03:08:24

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sources.redhat.com/ml/#faqs>
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 <manfred AT colorfullife DOT com>
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

--------------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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019