Re: a recursion bug

2012-10-03 Thread Greg Wooledge
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

2012-10-03 Thread Chet Ramey
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

2012-10-03 Thread Greg Wooledge
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

2012-10-03 Thread Yuxiang Cao
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

2012-10-03 Thread Linda A. Walsh

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

2012-10-03 Thread Bob Proulx
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

2012-10-03 Thread Greg Wooledge
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

2012-10-03 Thread Chet Ramey
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

2012-10-03 Thread Eric Blake
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

2012-10-03 Thread Bob Proulx
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

2012-10-03 Thread Bob Proulx
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