Re: a recursion bug
On Wed, Oct 03, 2012 at 05:07:16AM +, Yuxiang Cao wrote: > Hi, > After second thought, I carefully read the bash manual page and find this > information. Functions may be recursive. The FUNCNEST variable may be used to > limit the depth of the function call stack and restrict the number of > function invocations. By default, no limit is placed on the number of > recursive calls. So in my example, what I think I can do is to limit the > times of recursive calls. So I simply export FUNCNEST variable as " export > FUNCNEST=500", however, it doesn't work. That could be a bug for bash, right? It would help if you show what you're doing and what the result is. It seems to work correctly here: imadev:~$ bash-4.2.28 -c 'FUNCNEST=100; a() { echo "$1"; a $(($1+1)); }; a 1' 2>&1 | tail 92 93 94 95 96 97 98 99 100 bash-4.2.28: a: maximum function nesting level exceeded (100) Without the FUNCNEST, it runs for several seconds, and then: imadev:~$ bash-4.2.28 -c 'a() { echo "$1"; a $(($1+1)); }; a 1' 2>&1 | tail Pid 4466 received a SIGSEGV for stack growth failure. Possible causes: insufficient memory or swap space, or stack size exceeded maxssiz. 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 imadev:~$ ls -l core -rw--- 1 wooledgpgmr 19908052 Oct 3 08:38 core imadev:~$ file core core: core file from 'bash-4.2.28' - received SIGSEGV (Happy, Linda?)
Re: a recursion bug
On 10/3/12 9:09 AM, Yuxiang Cao wrote: > Hi, > Actually, I just change to Solaris system and running your code which still > not work. FUNCNEST is a bash-4.2 feature, which you're apparently not running. -- ``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: a recursion bug
On Wed, Oct 03, 2012 at 01:00:21PM +, Yuxiang Cao wrote: > Hi, this is a interesting problem. Because My bash version is 4.1.5, so I > simply run the similar thing as your code which give me this > frank@frank-laptop:~/research/realfault$ bash -c 'FUNCNEST=100; a() { echo > "$1"; a $(($1+1)); }; a 1' 2>&1 | tail When I look in "man bash" on a Debian system with bash 4.1, there is no FUNCNEST, so it was probably added in version 4.2. That's why it isn't working for you.
RE: a recursion bug
Hi, Actually, I just change to Solaris system and running your code which still not work. Regards, Yuxiang Cao From: Yuxiang Cao Sent: Wednesday, October 03, 2012 11:00 PM To: Greg Wooledge Subject: RE: a recursion bug Hi, this is a interesting problem. Because My bash version is 4.1.5, so I simply run the similar thing as your code which give me this frank@frank-laptop:~/research/realfault$ bash -c 'FUNCNEST=100; a() { echo "$1"; a $(($1+1)); }; a 1' 2>&1 | tail 17692 17693 17694 17695 17696 17697 17698 17699 17700 17701 I think it is not work on Ubuntu 10.4, and that is my OS. Here is my code #!/bin/bash FUNCNEST=100 recursion() { if [ $1 -ne 15000 ] ;then echo $1 let i=$1+1 recursion $i fi exit } recursion 1 whatever i set FUNCNEST value in my script or export FUNCNEST=100. It is still not work. That is weird. From: Greg Wooledge [wool...@eeg.ccf.org] Sent: Wednesday, October 03, 2012 10:40 PM To: Yuxiang Cao Cc: bug-bash@gnu.org Subject: Re: a recursion bug On Wed, Oct 03, 2012 at 05:07:16AM +, Yuxiang Cao wrote: > Hi, > After second thought, I carefully read the bash manual page and find this > information. Functions may be recursive. The FUNCNEST variable may be used to > limit the depth of the function call stack and restrict the number of > function invocations. By default, no limit is placed on the number of > recursive calls. So in my example, what I think I can do is to limit the > times of recursive calls. So I simply export FUNCNEST variable as " export > FUNCNEST=500", however, it doesn't work. That could be a bug for bash, right? It would help if you show what you're doing and what the result is. It seems to work correctly here: imadev:~$ bash-4.2.28 -c 'FUNCNEST=100; a() { echo "$1"; a $(($1+1)); }; a 1' 2>&1 | tail 92 93 94 95 96 97 98 99 100 bash-4.2.28: a: maximum function nesting level exceeded (100) Without the FUNCNEST, it runs for several seconds, and then: imadev:~$ bash-4.2.28 -c 'a() { echo "$1"; a $(($1+1)); }; a 1' 2>&1 | tail Pid 4466 received a SIGSEGV for stack growth failure. Possible causes: insufficient memory or swap space, or stack size exceeded maxssiz. 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 imadev:~$ ls -l core -rw--- 1 wooledgpgmr 19908052 Oct 3 08:38 core imadev:~$ file core core: core file from 'bash-4.2.28' - received SIGSEGV (Happy, Linda?)
Re: a recursion bug
Steven W. Orr wrote: I think there's a fundamental misunderstanding between the difference of an error code returned by a system call and the exit status of a process. They're two completely different things. It's not a fundamental misunderstanding. It's a fundamental belief in using data bandwidth and not wasting it. If 0=ok, as it does in bash and with errno, and, it is the case (still is), that errno's fit in 1 byte, there's no reason not to return the exact failure mode from a util... That's not to say that many or most do -- some even return a status of '0' on fatal errors (xfs_mkfile -- on running out of room returns a status 0). Just for fun, look at the man page for grep. It is advertised to return a 0, 1 or 2. The actual values of errno that might happen in the middle are a separate problem. Like I said, it's a fundamental waste of bits. But -- if it encountered an error, should it issue a SEGV and coredump message, or should it terminate the wayward script/function and return to the prompt? Hey you can do whatever, but if the linux kernel crashed on every resource strain, most people would consider that bad.
Re: a recursion bug
Linda A. Walsh wrote: > Steven W. Orr wrote: > >I think there's a fundamental misunderstanding between the > >difference of an error code returned by a system call and the exit > >status of a process. They're two completely different things. > > It's not a fundamental misunderstanding. It's a fundamental belief > in using data bandwidth and not wasting it. If 0=ok, as it does in bash and > with errno, and, it is the case (still is), that errno's fit in 1 byte, > there's no reason not to return the exact failure mode from a util... I still think there is the misunderstanding of the OP's case between bash and the run of it under valgrind. I think you are still talking about the valgrind part of the run. But in any case, is there anything in there that is about bash? If so the we need an exact test case. If not then let's not discuss it here. > That's not to say that many or most do -- some even return a status > of '0' on fatal errors (xfs_mkfile -- on running out of room returns a status > 0). What xfs utils do or don't do is off topic for the bug-bash list. > >Just for fun, look at the man page for grep. It is advertised to > >return a 0, 1 or 2. The actual values of errno that might happen > >in the middle are a separate problem. > > Like I said, it's a fundamental waste of bits. > > But -- if it encountered an error, should it issue a SEGV and > coredump message, or should it terminate the wayward script/function > and return to the prompt? This is just the result of "Worse is Better". It is one of the fundamentals that made Unix the wondeful system that we know it to be today. You may not like it but it is a principle that has strongly shaped the system. http://en.wikipedia.org/wiki/Worse_is_better The problem you are fighting is that every program on the system is governed by kernel stack limits. If the program exceeds the policy limit then it will get a SIGSEGV for stack growth failure. Now it is possible for a program to go to extreme efforts to trap that case and to deal explicitly with it. But it isn't worth it. Worse is better. Better is an easy to maintain portable program. Trying to deal with every possible problem on every possible system in every possible context will yield a worse solution. Don't do it. In the immortal words of Smith & Dale: SMITH: Doctor, it hurts when I do this. DALE: Don't do that. > Hey you can do whatever, but if the linux kernel crashed on every > resource strain, most people would consider that bad. This is a reductio ad absurdum ("reduction to absurdity") argument that doesn't apply here. The linux kernel was not crashing. This is off the topic. Bob
Re: a recursion bug
On Wed, Oct 03, 2012 at 01:23:58PM -0600, Bob Proulx wrote: > But in any case, is there > anything in there that is about bash? If so the we need an exact test > case. You could start with this one: imadev:~$ bash-4.2.28 -c 'a() { echo "$1"; a $(($1+1)); }; a 1' 2>&1 | tail Pid 4466 received a SIGSEGV for stack growth failure. Possible causes: insufficient memory or swap space, or stack size exceeded maxssiz. 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 imadev:~$ ls -l core -rw--- 1 wooledgpgmr 19908052 Oct 3 08:38 core imadev:~$ file core core: core file from 'bash-4.2.28' - received SIGSEGV That was executed on HP-UX 10.20. I agree that bash should try not to dump core in this case, if it's reasonable to prevent it. There was some confusion in the earlier part of this thread due to the introduction of valgrind into the picture, and incomplete quoting of previous messages.
Re: a recursion bug
On 10/3/12 3:40 PM, Greg Wooledge wrote: > On Wed, Oct 03, 2012 at 01:23:58PM -0600, Bob Proulx wrote: >> But in any case, is there >> anything in there that is about bash? If so the we need an exact test >> case. > > You could start with this one: > > imadev:~$ bash-4.2.28 -c 'a() { echo "$1"; a $(($1+1)); }; a 1' 2>&1 | tail > > Pid 4466 received a SIGSEGV for stack growth failure. > Possible causes: insufficient memory or swap space, > or stack size exceeded maxssiz. There's not actually anything you can do about that except use ulimit to get as much stack space as you can. -- ``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: a recursion bug
On 10/03/2012 01:23 PM, Bob Proulx wrote: >> But -- if it encountered an error, should it issue a SEGV and >> coredump message, or should it terminate the wayward script/function >> and return to the prompt? > > This is just the result of "Worse is Better". It is one of the > fundamentals that made Unix the wondeful system that we know it to be > today. You may not like it but it is a principle that has strongly > shaped the system. > > http://en.wikipedia.org/wiki/Worse_is_better > > The problem you are fighting is that every program on the system is > governed by kernel stack limits. If the program exceeds the policy > limit then it will get a SIGSEGV for stack growth failure. > > Now it is possible for a program to go to extreme efforts to trap that > case and to deal explicitly with it. But it isn't worth it. Worse is > better. Better is an easy to maintain portable program. Trying to > deal with every possible problem on every possible system in every > possible context will yield a worse solution. Don't do it. libsigsegv has already tackled this problem, making it very easy to detect user-induced stack overflow with a minimum amount of additional code. Both GNU m4 and gawk have used libsigsegv to implement nicer error handling in this situation, so maybe it is worth copying code from these projects into bash. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: a recursion bug
Greg Wooledge wrote: > imadev:~$ bash-4.2.28 -c 'a() { echo "$1"; a $(($1+1)); }; a 1' 2>&1 | tail > Pid 4466 received a SIGSEGV for stack growth failure. > Possible causes: insufficient memory or swap space, > or stack size exceeded maxssiz. > 6534 > 6535 > 6536 > 6537 > 6538 > 6539 > 6540 > 6541 > 6542 > 6543 > imadev:~$ ls -l core > -rw--- 1 wooledgpgmr 19908052 Oct 3 08:38 core > imadev:~$ file core > core: core file from 'bash-4.2.28' - received SIGSEGV > > That was executed on HP-UX 10.20. I agree that bash should try not > to dump core in this case, if it's reasonable to prevent it. HP-UX is a traditional Unix system and traditionally the system always enabled core dumps. How useful those were to people is another question. So by the above you are suggesting that bash should be re-written to use and maintain a userspace stack? That would convert stack memory use into heap memory use. Or are you suggesting that bash should add code to trap SIGSEGV, determine if it was due to insufficient stack memory and if so then exit with a nicer message? Or are you suggesting that bash should specify its own stack area so as to avoid the system stack size limitation? I could see either of those first two solutions being reasonable. Bob
Re: a recursion bug
Chet Ramey wrote: > > Pid 4466 received a SIGSEGV for stack growth failure. > > Possible causes: insufficient memory or swap space, > > or stack size exceeded maxssiz. > > There's not actually anything you can do about that except use ulimit to > get as much stack space as you can. Well... There is the gnulib c-stack module: http://www.gnu.org/software/gnulib/MODULES.html c-stack Stack overflow handling, causing program exit. Bob