Re: [bug-bash] Named fifo's causing hanging bash scripts

2015-01-13 Thread Dr. Werner Fink
On Mon, Jan 12, 2015 at 11:50:56AM -0500, Chet Ramey wrote:
> On 1/12/15 9:55 AM, wer...@linux-8jdz.site wrote:
> > Configuration Information [Automatically generated, do not change]:
> > Machine: x86_64
> > OS: linux-gnu
> > Compiler: gcc -I/home/abuild/rpmbuild/BUILD/bash-4.3 
> > -L/home/abuild/rpmbuild/BUILD/bash-4.3/../readline-6.3
> > Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
> > -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-suse-linux-gnu' 
> > -DCONF_VENDOR='suse' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' 
> > -DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib   -fmessage-length=0 
> > -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector 
> > -funwind-tables -fasynchronous-unwind-tables -g  -D_GNU_SOURCE 
> > -DRECYCLES_PIDS -Wall -g -Wuninitialized -Wextra -Wno-unprototyped-calls 
> > -Wno-switch-enum -Wno-unused-variable -Wno-unused-parameter 
> > -Wno-parentheses -ftree-loop-linear -pipe -DBNC382214=0 
> > -DMUST_UNBLOCK_CHLD=1 -DIMPORT_FUNCTIONS_DEF=0 -fprofile-use
> > uname output: Linux d136 3.15.0-rc7-3-desktop #1 SMP PREEMPT Wed May 28 
> > 15:39:51 UTC 2014 (96f5b60) x86_64 x86_64 x86_64 GNU/Linux
> > Machine Type: x86_64-suse-linux-gnu
> > 
> > Bash Version: 4.3
> > Patch Level: 33
> > Release Status: release
> > 
> > Description:
> > Named fifo's causing hanging bash scripts like
> > 
> > while IFS="|" read a b c ; do
> >   [shell code]
> > done < <(shell code)
> > 
> > can cause random hangs of the bash.An strace shows that the bash
> > stays in wait4()
> 
> And when you attach to one of the hanging bash processes using gdb, what
> does the stack traceback look like?

Yes (and sorry for the wrong email address as this was done on a clean virtual 
sysstem)

there are two hanging bash processes together with the find command:

werner   19062  0.8  0.0  11864  2868 ttyS0S+   10:21   0:00 bash -x 
/tmp/brp-25-symlink
werner   19063  0.0  0.0  11860  1920 ttyS0S+   10:21   0:00 bash -x 
/tmp/brp-25-symlink
werner   19064  0.2  0.0  16684  2516 ttyS0S+   10:21   0:00 find . -type l 
-printf %p|%h|%l n

the gdb -p 19062 and gdb -p 19063 show

(gdb) bt
#0  0x7f530818a65c in waitpid () from /lib64/libc.so.6
#1  0x0042b233 in waitchld (block=block@entry=1, wpid=19175) at 
jobs.c:3235
#2  0x0042c6da in wait_for (pid=pid@entry=19175) at jobs.c:2496
#3  0x004302e1 in command_substitute (string=string@entry=0x22ccd80 
"dirname_int $link", 
quoted=quoted@entry=1) at subst.c:5534
#4  0x004704db in param_expand (string=string@entry=0x22cc8d0 
"$(dirname_int $link)", 
sindex=sindex@entry=0x7fff39f90ef0, quoted=quoted@entry=1, 
expanded_something=expanded_something@entry=0x0, 
contains_dollar_at=contains_dollar_at@entry=0x7fff39f90f20, 
quoted_dollar_at_p=quoted_dollar_at_p@entry=0x7fff39f90f00, 
had_quoted_null_p=had_quoted_null_p@entry=0x7fff39f90f10, pflags=0) at 
subst.c:7970
#5  0x00471123 in expand_word_internal (word=word@entry=0x22cc1a0, 
quoted=quoted@entry=1, 
isexp=isexp@entry=0, 
contains_dollar_at=contains_dollar_at@entry=0x7fff39f91080, 
expanded_something=expanded_something@entry=0x0) at subst.c:8393
#6  0x0047130f in expand_word_internal (word=word@entry=0x7fff39f91120, 
quoted=quoted@entry=0, 
isexp=isexp@entry=0, contains_dollar_at=contains_dollar_at@entry=0x0, 
expanded_something=expanded_something@entry=0x0) at subst.c:8548
#7  0x00472daf in call_expand_word_internal (e=0x0, c=0x0, i=0, q=0, 
w=0x7fff39f91120) at subst.c:3299
#8  expand_string_assignment (string=string@entry=0x22cb159 "\"$(dirname_int 
$link)\"", quoted=quoted@entry=0)
at subst.c:3387
#9  0x00473110 in expand_string_if_necessary (string=, 
string@entry=0x22cb159 "\"$(dirname_int $link)\"", quoted=quoted@entry=0, 
func=func@entry=0x472d50 ) at subst.c:3092
#10 0x00473349 in do_assignment_internal (word=0x22cbbe0, expand=1) at 
subst.c:2823
#11 0x0047776a in do_word_assignment (flags=, 
word=) at subst.c:2912
#12 expand_word_list_internal (eflags=, list=) at 
subst.c:9669
#13 expand_words (list=0x) at subst.c:9280
#14 0x00461093 in execute_simple_command (simple_command=0x22c1ed0, 
pipe_in=pipe_in@entry=-1, 
pipe_out=pipe_out@entry=-1, async=async@entry=0, 
fds_to_close=fds_to_close@entry=0x22ccce0)
at execute_cmd.c:4001
#15 0x004629fc in execute_command_internal (command=0x22bc9e0, 
asynchronous=asynchronous@entry=0, 
pipe_in=pipe_in@entry=-1, pipe_out=pipe_out@entry=-1, 
fds_to_close=fds_to_close@entry=0x22ccce0)
at execute_cmd.c:788
#16 0x00462ba6 in execute_connection (fds_to_close=0x22ccce0, 
pipe_out=-1, pipe_in=-1, asynchronous=0, 
command=0x22c0bd0) at execute_cmd.c:2497
#17 execute_command_internal (command=command@entry=0x22c0bd0, 
asynchronous=asynchronous@entry=0, 
pipe_in=pipe_in@entry=-1, pipe_out=p

CTL-z bug?

2015-01-13 Thread Guillaume MULLER

Hi,

When I run a for loop in bash, then pausing it with CTL-z, then restarting it with fg, 
the for loop just stops. I don't think this was the behaviour until recently, and I don't 
find it a correct behaviour, according to the meaning of the CTL-z "suspend" 
(https://en.wikipedia.org/wiki/Control-Z). Is there any explanation to this behaviour?


I'm using:
GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)

Under:
Ubuntu 14.10 (utopic)

Cheers

GM



Re: CTL-z bug?

2015-01-13 Thread Chet Ramey
On 1/13/15 11:37 AM, Guillaume MULLER wrote:
> Hi,
> 
> When I run a for loop in bash, then pausing it with CTL-z, then restarting
> it with fg, the for loop just stops. I don't think this was the behaviour
> until recently, and I don't find it a correct behaviour, according to the
> meaning of the CTL-z "suspend" (https://en.wikipedia.org/wiki/Control-Z).
> Is there any explanation to this behaviour?

SIGTSTP works at the process or job level, not the shell compound command
level.  When you stop the current job with ^Z, the shell has a choice to
make: continue with the loop, or break out of it.  There isn't a handle to
suspend the entire loop's execution, since it doesn't execute in a
separate process.  Bash chooses to break the loop, and has done so for a
very long time (at least back to bash-3.0, which was released ten years
ago, at which point I stopped looking).

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: CTL-z bug?

2015-01-13 Thread Eduardo A . Bustamante López
I think that the following text from the zshell's code is an interesting read
on the subject:

TL;DR: Another strategy is to "migrate" the while-loop to a child process the
moment that you hit ^Z, but, this is really hard (maybe impossible?) to do
correctly.

(From Src/exec.c)

/*
 * [...]
 *
 * In most shells, if you do something like:
 *
 *   cat foo | while read a; do grep $a bar; done
 *
 * the shell forks and executes the loop in the sub-shell thus created.
 * In zsh this traditionally executes the loop in the current shell, which
 * is nice to have if the loop does something to change the shell, like
 * setting parameters or calling builtins.
 * Putting the loop in a sub-shell makes life easy, because the shell only
 * has to put it into the job-structure and then treats it as a normal
 * process. Suspending and interrupting is no problem then.
 * Some years ago, zsh either couldn't suspend such things at all, or
 * it got really messed up when users tried to do it. As a solution, we
 * implemented the list_pipe-stuff, which has since then become a reason
 * for many nightmares.
 * Pipelines like the one above are executed by the functions in this file
 * which call each other (and sometimes recursively). The one above, for
 * example would lead to a function call stack roughly like:
 *
 *  execlist->execpline->execcmd->execwhile->execlist->execpline
 *
 * (when waiting for the grep, ignoring execpline2 for now). At this time,
 * zsh has built two job-table entries for it: one for the cat and one for
 * the grep. If the user hits ^Z at this point (and jobbing is used), the
 * shell is notified that the grep was suspended. The list_pipe flag is
 * used to tell the execpline where it was waiting that it was in a pipeline
 * with a shell construct at the end (which may also be a shell function or
 * several other things). When zsh sees the suspended grep, it forks to let
 * the sub-shell execute the rest of the while loop. The parent shell walks
 * up in the function call stack to the first execpline. There it has to find
 * out that it has just forked and then has to add information about the sub-
 * shell (its pid and the text for it) in the job entry of the cat. The pid
 * is passed down in the list_pipe_pid variable.
 * But there is a problem: the suspended grep is a child of the parent shell
 * and can't be adopted by the sub-shell. So the parent shell also has to
 * keep the information about this process (more precisely: this pipeline)
 * by keeping the job table entry it created for it. The fact that there
 * are two jobs which have to be treated together is remembered by setting
 * the STAT_SUPERJOB flag in the entry for the cat-job (which now also
 * contains a process-entry for the whole loop -- the sub-shell) and by
 * setting STAT_SUBJOB in the job of the grep-job. With that we can keep
 * sub-jobs from being displayed and we can handle an fg/bg on the super-
 * job correctly. When the super-job is continued, the shell also wakes up
 * the sub-job. But then, the grep will exit sometime. Now the parent shell
 * has to remember not to try to wake it up again (in case of another ^Z).
 * It also has to wake up the sub-shell (which suspended itself immediately
 * after creation), so that the rest of the loop is executed by it.
 * But there is more: when the sub-shell is created, the cat may already
 * have exited, so we can't put the sub-shell in the process group of it.
 * In this case, we put the sub-shell in the process group of the parent
 * shell and in any case, the sub-shell has to put all commands executed
 * by it into its own process group, because only this way the parent
 * shell can control them since it only knows the process group of the sub-
 * shell. Of course, this information is also important when putting a job
 * in the foreground, where we have to attach its process group to the
 * controlling tty.
 * All this is made more difficult because we have to handle return values
 * correctly. If the grep is signaled, its exit status has to be propagated
 * back to the parent shell which needs it to set the exit status of the
 * super-job. And of course, when the grep is signaled (including ^C), the
 * loop has to be stopped, etc.
 * The code for all this is distributed over three files (exec.c, jobs.c,
 * and signals.c) and none of them is a simple one. So, all in all, there
 * may still be bugs, but considering the complexity (with race conditions,
 * signal handling, and all that), this should probably be expected.
 */

I hope this explains why bash does what it does.