NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/41230: -current: sh(1) endlessly looping in interactive mode



>Number:         41230
>Category:       bin
>Synopsis:       -current: sh(1) endlessly looping in interactive mode
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Apr 16 15:15:00 +0000 2009
>Originator:     Matthew Mondor
>Release:        NetBSD 5.99.10
>Organization:
>Environment:
System: NetBSD sat.xisop 5.99.10 NetBSD 5.99.10 (GENERIC_MM) #0: Wed Apr 15 
17:31:57 EDT 2009  
root%sat.xisop@localhost:/usr/obj/sys/arch/i386/compile/GENERIC_MM i386
Architecture: i386
Machine: i386
>Description:

On -current, /bin/sh becomes stuck in an endless loop when started
as an interactive login shell with the following configuration:


~/.profile
==========

if [ -x /usr/bin/tset ]; then
       eval `tset -sQrm 'unknown:?unknown'`
fi

export ENV=$HOME/.shrc


~/.shrc
=======

. /etc/profile

hup(){ (read pid; kill -HUP $pid) </var/run/$1.pid; }
ll(){ ls -l ${1+"$@"}; }

# Only do this if called in interactive mode
case "$-" in *i*)
        set -o emacs
        if [ $SHELL = '/bin/sh' ]; then
                set -o tabcomplete
        fi
        alias exit='clear; exit'

        prompt()
        {
                if [ $(/usr/bin/id -u) -eq 0 ]; then
                        echo '#'
                else
                        echo '$'
                fi
        }

        export PS1=" --- ($(/usr/bin/tty | /usr/bin/sed 's/\/dev\///')) 
$USER@$(/bin/hostname) $(prompt) "

        alias mv='mv -i'
        alias rm='rm -i'
        alias cp='cp -i'

        ;;
esac

umask 022


Details
=======

An example prompts generated above would be:
 --- (pts/4) mmondor%sat.xisop@localhost $
 --- (pts/1) mmondor%sat.xisop@localhost #

After building /bin/sh and libedit+libreadline with debug symbols, it
was possible to attach gdb to the sh(1) process stuck in the endless
loop:

 --- (pts/6) root%sat.xisop@localhost # gdb /bin/sh 5454
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386--netbsdelf"...
Attaching to program: /bin/sh, process 5454
Reading symbols from /lib/libedit.so.3...done.
Loaded symbols for /lib/libedit.so.3
Reading symbols from /lib/libtermcap.so.0...done.
Loaded symbols for /lib/libtermcap.so.0
Reading symbols from /lib/libc.so.12...done.
Loaded symbols for /lib/libc.so.12
Reading symbols from /libexec/ld.elf_so...done.
Loaded symbols for /libexec/ld.elf_so
0xbbbd6b5e in prompt_print (el=0xbb906800, op=0) at prompt.c:97
97              while (*p) {
(gdb) bt
#0  0xbbbd6b5e in prompt_print (el=0xbb906800, op=0) at prompt.c:97
#1  0xbbbd7d07 in re_refresh (el=0xbb906800) at refresh.c:220
#2  0xbbbd7317 in read_prepare (el=0xbb906800) at read.c:394
#3  0xbbbd74be in el_gets (el=0xbb906800, nread=0x8069670) at read.c:472
#4  0x08053798 in preadfd () at input.c:185
#5  0x0805397c in preadbuffer () at input.c:255
#6  0x0805a818 in xxreadtoken () at parser.c:816
#7  0x0805a64c in readtoken () at parser.c:736
#8  0x08059568 in parsecmd (interact=1) at parser.c:139
#9  0x0805737a in cmdloop (top=1) at main.c:250
#10 0x080572e7 in main (argc=1, argv=0xbfbfeeb8) at main.c:215
(gdb) info local
elp = (el_prompt_t *) 0xbb906a24
p = 0xbb904121 "p $ "
ignore = 1
(gdb) step
98                      if (elp->p_ignore == *p) {
(gdb) step
99                              ignore = !ignore;
(gdb) step
100                             continue;
(gdb) step
97              while (*p) {  
(gdb) step
98                      if (elp->p_ignore == *p) {
(gdb) step
99                              ignore = !ignore;
(gdb) step
100                             continue;
[...]
(gdb) print *elp
$2 = {p_func = 0x805c9c3 <getprompt>, p_pos = {h = 0, v = 0},
  p_ignore = 112 'p'}
(gdb)

Commenting out the "continue;" above indeed stopped the problem,
but obviously the prompt wasn't printed properly without it.
I've not had time to read more throughly the prompt related code,
but decided to file a PR now (and add it to my to-track list).

>How-To-Repeat:
>Fix:



Home | Main Index | Thread Index | Old Index