Hi Mike,
As earlier expained, you are calling foo function recursively. To mitigate
this behaviour you simple set FUNCNEST= foo() { foo; }; foo where N
denotes the number of nested functios to be called.
Op zo 7 okt. 2018 07:57 schreef Mike Gerwitz :
> Hey, Bob!
>
> On Sat, Oct 06, 2018 at 22:44:17 -0600, Bob Proulx wrote:
> > Let me give the discussion this way and I think you will be
> > convinced. :-)
>
> Well, thanks for taking the time for such a long reply. :)
>
> > How is your example any different from a C program? Or Perl, Python,
> > Ruby, and so forth? All of those also allow infinite recursion and
> > the kernel will terminate them with a segfault. Because all of those
> > also allow infinite recursion. A program that executes an infinite
> > recursion would use infinite stack space. But real machines have a
> > finite amount of stack available and therefore die when the stack is
> > exceeded.
>
> I expect this behavior when writing in C, certainly. But in languages
> where the user does not deal with memory management, I'm used to a more
> graceful abort when the stack gets out of control. A segfault means
> something to a C hacker. It means very little to users who are
> unfamiliar with the concepts that you were describing.
>
> I don't have enough experience with Perl, Python, or Ruby to know how
> they handle stack issues. But, out of interest, I gave it a try:
>
> $ perl -e 'sub foo() { foo(); }; foo()'
> Out of memory!
>
> $ python <<< 'def foo():
> > foo()
> >foo()' |& tail -n1
> RuntimeError: maximum recursion depth exceeded
>
> $ ruby -e 'def foo()
> > foo()
> > end
> > foo()'
> -e:2: stack level too deep (SystemStackError)
>
> Some languages I'm more familiar with:
>
> $ node -e '(function foo() { foo(); })()'
> [eval]:1
> (function foo() { foo(); })()
>^
>
> RangeError: Maximum call stack size exceeded
>
> $ php -r 'function foo() { foo(); } foo();'
>
> Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to
> allocate 262144 bytes) in Command line code on line 1
>
> $ guile -e '(let x () (+ (x)))'
> allocate_stack failed: Cannot allocate memory
> Warning: Unwind-only `stack-overflow' exception; skipping pre-unwind
> handler.
>
> $ emacs --batch --eval '(message (defun foo () (foo)) (foo))'
> Lisp nesting exceeds ‘max-lisp-eval-depth’
>
> And so on.
>
> I understand that in C you usually don't manage your own stack and,
> consequently, you can't say that it falls under "memory management" in
> the sense of malloc(3) and brk(2) and such. But C programmers are aware
> of the mechanisms behind the stack (or at least better be) and won't be
> surprised when they get a segfault in this situation.
>
> But if one of my coworkers who knows some web programming and not much
> about system programming gets a segfault, that's not a friendly
> error. If Bash instead said something like the above languages, then
> that would be useful.
>
> When I first saw the error, I didn't know that my trap was
> recursing. My immediate reaction was "shit, I found a bug". Once I saw
> it was the trap, I _assumed_ it was just exhausting the stack, but I
> wanted to report it regardless, just in case; I didn't have the time to
> dig deeper, and even so, I wasn't sure if it was intended behavior to
> just let the kernel handle it.
>
>
> > This following complete C program recurses infinitely. Or at least
> > until the stack is exhausted. At which time it triggers a segfault
> > because it tries to use memory beyond the page mapped stack.
>
> [...]
>
> > Would you say that is a bug in the C language? A bug in gcc that
> > compiled it? A bug in the Unix/Linux kernel for memory management
> > that trapped the error? The parent shell that reported the exit code
> > of the program? Or in the program source code? I am hoping that we
> > will all agree that it is a bug in the program source code and not
> > either gcc or the kernel. :-)
>
> I agree, yes.
>
> > Shell script code is program source code. Infinite loops or infinite
> > recursion are bugs in the shell script source code not the interpreter
> > that is executing the code as written.
>
> I also agree. But the context is very different. Shell is a very,
> very high-level language.
>
> > This feels to me to be related to The Halting Problem.
>
> Knowing in advance whether there may be a problem certainly is, but we
> don't need to do that; we'd just need to detect it at runtime to provide
> a more useful error message.
>
> > Other shells are also fun to check:
> >
> > $ dash -c 'trap "kill 0" TERM; kill 0'
> > Segmentation fault
> >
> > $ ash -c 'trap "kill 0" TERM; kill 0'
> > Segmentation fault
> >
> > $ mksh -c 'trap "kill 0" TERM; kill 0'
> > Segmentation fault
>
> Heh, interesting!
>
> > $ ksh93 -c 'trap "kill 0" TERM; kill 0'
> > $ echo $?
> > 0
>
> This is not the behavior I'd want.
>
> > $ posh -c 'trap "kill 0" TERM; kill 0'
>