A possible bug on autocompletion after setting FUNCNEST level

2018-10-08 Thread Valentin Bajrami
This is some kind of a follow up on "Segfault on recursive trap/kill"
reported by Mike Grewitz.

After setting FUNCNEST and the listing a file or using 'vi filname[TAB]'  a
bug is triggered.

This is how I could reproduce this:

f3d0r4:~/FOO# FUNCNEST=4

f3d0r4:~/FOO# ls
procps-ng-3.3.12-3.fc28.src.rpm
procps-ng-3.3.12-pmap-all-lines-twice.patch  procps-ng-3.3.12.tar.xz
procps-ng-3.3.14-CVE-2018-1124.patch  procps-ng.spec  README.md  README.top

f3d0r4:~/FOO# vi pr-bash: __reassemble_comp_words_by_ref: maximum function
nesting level exceeded (4)

f3d0r4:~/FOO# echo "$BASH_VERSION"
4.4.23(1)-release

f3d0r4:~/FOO# ls pr-bash: __reassemble_comp_words_by_ref: maximum function
nesting level exceeded (4)

f3d0r4:~/FOO# set -x
++ printf '\033]0;%s@%s:%s\007' root f3d0r4 '~/FOO'
f3d0r4:~/FOO# ls pr+ local cur prev words cword split
+ _init_completion -s
+ local exclude= flag outx errx inx OPTIND=1
+ getopts n:e:o:i:s flag -s
+ case $flag in
+ split=false
+ exclude+==
+ getopts n:e:o:i:s flag -s
+ COMPREPLY=()
+ local 'redir=@(?([0-9])<|?([0-9&])>?(>)|>&)'
+ _get_comp_words_by_ref -n '=<>&' cur prev words cword
+ local exclude flag i OPTIND=1
+ words=()
+ local cur cword words
+ upargs=()
+ upvars=()
+ local upargs upvars vcur vcword vprev vwords
+ getopts c:i:n:p:w: flag -n '=<>&' cur prev words cword
+ case $flag in
+ exclude='=<>&'
+ getopts c:i:n:p:w: flag -n '=<>&' cur prev words cword
+ [[ 6 -ge 3 ]]
+ case ${!OPTIND} in
+ vcur=cur
+ let 'OPTIND += 1'
+ [[ 6 -ge 4 ]]
+ case ${!OPTIND} in
+ vprev=prev
+ let 'OPTIND += 1'
+ [[ 6 -ge 5 ]]
+ case ${!OPTIND} in
+ vwords=words
+ let 'OPTIND += 1'
+ [[ 6 -ge 6 ]]
+ case ${!OPTIND} in
+ vcword=cword
+ let 'OPTIND += 1'
+ [[ 6 -ge 7 ]]
+ __get_cword_at_cursor_by_ref '=<>&' words cword cur
+ words=()
+ local cword words
+ __reassemble_comp_words_by_ref '=<>&' words cword
-bash: __reassemble_comp_words_by_ref: maximum function nesting level
exceeded (4)
++ printf '\033]0;%s@%s:%s\007' root f3d0r4 '~/FOO'

Especially the following line:  bash: __reassemble_comp_words_by_ref:
maximum function nesting level exceeded (4)

-- 
Met vriendelijke groet,

Valentin Bajrami


Re: A possible bug on autocompletion after setting FUNCNEST level

2018-10-08 Thread Andreas Schwab
On Okt 08 2018, Valentin Bajrami  wrote:

> This is some kind of a follow up on "Segfault on recursive trap/kill"
> reported by Mike Grewitz.
>
> After setting FUNCNEST and the listing a file or using 'vi filname[TAB]'  a
> bug is triggered.
>
> This is how I could reproduce this:
>
> f3d0r4:~/FOO# FUNCNEST=4
>
> f3d0r4:~/FOO# ls
> procps-ng-3.3.12-3.fc28.src.rpm
> procps-ng-3.3.12-pmap-all-lines-twice.patch  procps-ng-3.3.12.tar.xz
> procps-ng-3.3.14-CVE-2018-1124.patch  procps-ng.spec  README.md  README.top
>
> f3d0r4:~/FOO# vi pr-bash: __reassemble_comp_words_by_ref: maximum function
> nesting level exceeded (4)

In which way is this a bug?  AFAICT, FUNCNEST is doing its job.

Andreas.

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."



Re: A possible bug on autocompletion after setting FUNCNEST level

2018-10-08 Thread Chet Ramey
On 10/8/18 8:06 AM, Valentin Bajrami wrote:
> This is some kind of a follow up on "Segfault on recursive trap/kill"
> reported by Mike Grewitz.
> 
> After setting FUNCNEST and the listing a file or using 'vi filname[TAB]'  a
> bug is triggered.

It's not a bug. FUNCNEST is working as designed. As a side effect, you
have limited functionality enough that bash-completion can't work.

Chet

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



Re: A possible bug on autocompletion after setting FUNCNEST level

2018-10-08 Thread Greg Wooledge
On Mon, Oct 08, 2018 at 02:06:39PM +0200, Valentin Bajrami wrote:
> This is how I could reproduce this:
> 
> f3d0r4:~/FOO# FUNCNEST=4

4 is ridiculously low.  Set it higher.



Re: Auto-update program cache feature

2018-10-08 Thread Chet Ramey
On 10/6/18 4:23 PM, Bob Proulx wrote:
> Jeffrey Walton wrote:
>> I think a useful feature for Bash would be to automatically update the
>> program cache after an install.
> 
> Put this in your ~/.bashrc file and I believe your use case will be
> much happier.
> 
>   shopt -s checkhash

How many installers put a new version of an existing package into a
possibly-different directory with a different name? Even using a symlink
pointing to a new name would not trigger this behavior.

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



Re: Auto-update program cache feature

2018-10-08 Thread Bob Proulx
Chet Ramey wrote:
> Bob Proulx wrote:
> > Put this in your ~/.bashrc file and I believe your use case will be
> > much happier.
> > 
> >   shopt -s checkhash
> 
> How many installers put a new version of an existing package into a
> possibly-different directory with a different name? Even using a symlink
> pointing to a new name would not trigger this behavior.

The use case (reading between the lines) had to do with ping-pong'ing
between /usr/bin and /usr/local/bin though.  And I know that without
checkhash that I used to see that condition too.  But with checkhash
the complaint (from me) went away entirely.  I admit I didn't look at
it in great detail here now because I have had checkhash in use for so
long and not seen this problem since.  I'll need to experiment.

Bob



Re: Segfault on recursive trap/kill

2018-10-08 Thread Bob Proulx
Mike Gerwitz wrote:
> 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:

Some of those must be maintaining the stack in program data space
instead of in the machine stack space.  (shrug)

>   $ perl -e 'sub foo() { foo(); }; foo()'
>   Out of memory!

Perl apparently will let you use all available memory without
limitation.

>   $ python <<< 'def foo():
>   >  foo()
>   >foo()' |& tail -n1
>   RuntimeError: maximum recursion depth exceeded
>...

I wonder how they decide to set the depth.

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

134M seems arbitrarily small but at least it does say exactly what it
is doing there.

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

I think these two are different.  It looks like guile is using
libunwind to set up a stack exception handler whereas emacs appears to
be using a tracked max-lisp-eval-depth variable defaulting to 800 on
my system in emacs v25.

This limit serves to catch infinite recursions for you before they cause
actual stack overflow in C, which would be fatal for Emacs.
You can safely make it considerably larger than its default value,
if that proves inconveniently small.  However, if you increase it too far,
Emacs could overflow the real C stack, and crash.

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

My interpretation of the above is that you would want bash to use
libunwind (or whatever is appropriate) to set up a stack overflow
exception trap in order to handle stack overflow specially and then to
make an improved error reporting to the user when it happens.

Frankly I wasn't even aware of libunwind before this.  And haven't
learned enough about it to even know if that is what I should be
mentioning here yet. :-)

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

My mind reels at the statement, "Shell is a very, very high-level
language."  What?!  The shell is a very simple low level command and
control language.  It is very good at what it does.  But if one needs
to do high level things then one should switch over to a high level
language. :-)

> > Hope this helps!
> 
> There was useful information, yes.

After sifting out the non-useful information.  :-)

> I hope I was able to further clarify my concerns as well.

You are always eloquent! :-)

Bob


signature.asc
Description: PGP signature


Re: Segfault on recursive trap/kill

2018-10-08 Thread Mike Gerwitz
On Mon, Oct 08, 2018 at 11:59:53 -0600, Bob Proulx wrote:
> Some of those must be maintaining the stack in program data space
> instead of in the machine stack space.  (shrug)

Indeed.  But as I mentioned in another comment, such an implementation
detail shouldn't matter to the user IMO.

> My interpretation of the above is that you would want bash to use
> libunwind (or whatever is appropriate) to set up a stack overflow
> exception trap in order to handle stack overflow specially and then to
> make an improved error reporting to the user when it happens.

Either handle SIGSEGV and output a user-friendly message or do something
like FUNCNEST does today.  libunwind wouldn't be necessary, but I
don't know enough about it to say whether or not it may be useful.

But seeing as how the segfault isn't a bug after all (I'd consider it a
lack of a feature to provide the user with a more useful message), I'm
no longer concerned.  But if someone _is_ interested in providing an
improvement, I think it'd be a good one to have.  I unfortunately am
stretched far too thin to work on a patch.

>> I also agree.  But the context is very different.  Shell is a very,
>> very high-level language.
>
> My mind reels at the statement, "Shell is a very, very high-level
> language."  What?!  The shell is a very simple low level command and
> control language.  It is very good at what it does.  But if one needs
> to do high level things then one should switch over to a high level
> language. :-)

I mean "high level" in the sense that machine code is low-level, x86
assembly is somewhat high-level (because it was designed for use by a
programmer and includes many conveniences for doing so), C is
high-level, Perl/Python/etc are very high-level, and Bash is so
high-level that you're dealing with process manipulation---something
very far abstracted from how a computer actually works.

So, high-level in the sense of:
  https://en.wikipedia.org/wiki/High-level_programming_language

> After sifting out the non-useful information.  :-)

That information was useful information regardless of whether I was
aware of it. :)  I'm sure I'm not the only person who read your message.

> You are always eloquent! :-)

You as well!

-- 
Mike Gerwitz


signature.asc
Description: PGP signature