Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Zsh spins in endless loop with SIGHUP + read in zshexit



Hi,

I'm using `read` in `zshexit` and when my terminal crashes (e.g. XTerm gets
killed or ssh connection dies) Zsh spins in an endless loop until I kill it
with SIGKILL (SIGTERM doesn't work).

```
zshexit()
{
    if [[ ${#${(M)${(f)"$(</proc/self/mountinfo)"}#*/ / rw,}} == 1 ]]
    then
        if read -rq junk"?Root filesystem is still read-write. Remount ro? (y/N) "
        then
            echo
            mount -o remount,ro / || sleep 4
        else
            echo
        fi
    fi
}
```

Here's a backtrace:

```
#0  0x00007fb6d84eda5d in sigprocmask () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00005643fcc03d83 in signal_unblock (set=...) at ../../Src/signals.c:274
#2  0x00007fb6d7fcee1a in raw_getbyte (full=0, cptr=0x7fff401336af "", do_keytmout=0) at ../../../Src/Zle/zle_main.c:844
#3  getbyte (do_keytmout=0, timeout=0x0, full=full@entry=0) at ../../../Src/Zle/zle_main.c:880
#4  0x00007fb6d7fd22ad in zle_main_entry (cmd=<optimized out>, ap=<optimized out>) at ../../../Src/Zle/zle_main.c:2142
#5  0x00005643fcbcbcb8 in zleentry (cmd=7) at ../../Src/init.c:1604
#6  0x00005643fcb9e9c8 in bin_read (name=<optimized out>, args=<optimized out>, ops=<optimized out>, func=<optimized out>) at ../../Src/builtin.c:6408
#7  0x00005643fcba013d in execbuiltin (args=<optimized out>, assigns=<optimized out>, bn=<optimized out>) at ../../Src/builtin.c:507
#8  0x00005643fcbb0b02 in execcmd_exec (state=state@entry=0x7fff40138420, eparams=eparams@entry=0x7fff401351a0, input=input@entry=0, output=output@entry=0, 
    how=<optimized out>, how@entry=18, last1=<optimized out>, last1@entry=2, close_if_forked=-1) at ../../Src/exec.c:4090
#9  0x00005643fcbb105f in execpline2 (state=state@entry=0x7fff40138420, pcode=<optimized out>, how=how@entry=18, input=0, output=0, last1=last1@entry=0)
    at ../../Src/exec.c:1927
#10 0x00005643fcbb1400 in execpline (state=state@entry=0x7fff40138420, slcode=<optimized out>, how=how@entry=18, last1=0) at ../../Src/exec.c:1658
#11 0x00005643fcbb2d60 in execlist (state=state@entry=0x7fff40138420, dont_change_job=dont_change_job@entry=1, exiting=exiting@entry=0)
    at ../../Src/exec.c:1413
#12 0x00005643fcbd92bc in execif (state=0x7fff40138420, do_exec=0) at ../../Src/loop.c:555
#13 0x00005643fcbaf96c in execcmd_exec (state=state@entry=0x7fff40138420, eparams=eparams@entry=0x7fff40136900, input=input@entry=0, output=output@entry=0, 
    how=<optimized out>, how@entry=18, last1=<optimized out>, last1@entry=2, close_if_forked=-1) at ../../Src/exec.c:3910
#14 0x00005643fcbb105f in execpline2 (state=state@entry=0x7fff40138420, pcode=<optimized out>, how=how@entry=18, input=0, output=0, last1=last1@entry=0)
    at ../../Src/exec.c:1927
#15 0x00005643fcbb1400 in execpline (state=state@entry=0x7fff40138420, slcode=<optimized out>, how=how@entry=18, last1=0) at ../../Src/exec.c:1658
#16 0x00005643fcbb2d60 in execlist (state=state@entry=0x7fff40138420, dont_change_job=dont_change_job@entry=1, exiting=exiting@entry=0)
    at ../../Src/exec.c:1413
#17 0x00005643fcbd92f8 in execif (state=0x7fff40138420, do_exec=0) at ../../Src/loop.c:576
#18 0x00005643fcbaf96c in execcmd_exec (state=state@entry=0x7fff40138420, eparams=eparams@entry=0x7fff40138060, input=input@entry=0, output=output@entry=0, 
    how=<optimized out>, how@entry=18, last1=<optimized out>, last1@entry=2, close_if_forked=-1) at ../../Src/exec.c:3910
#19 0x00005643fcbb105f in execpline2 (state=state@entry=0x7fff40138420, pcode=<optimized out>, how=how@entry=18, input=0, output=0, last1=last1@entry=0)
    at ../../Src/exec.c:1927
#20 0x00005643fcbb1400 in execpline (state=state@entry=0x7fff40138420, slcode=<optimized out>, how=how@entry=18, last1=0) at ../../Src/exec.c:1658
#21 0x00005643fcbb2d60 in execlist (state=state@entry=0x7fff40138420, dont_change_job=dont_change_job@entry=1, exiting=exiting@entry=0)
    at ../../Src/exec.c:1413
#22 0x00005643fcbb3202 in execode (p=p@entry=0x5643fd1b2270, dont_change_job=dont_change_job@entry=1, exiting=exiting@entry=0, 
    context=context@entry=0x5643fcc24b8d "shfunc") at ../../Src/exec.c:1192
#23 0x00005643fcbb40ab in runshfunc (prog=0x5643fd1b2270, wrap=0x0, name=0x7fb6d8003170 "zshexit") at ../../Src/exec.c:5974
#24 0x00005643fcbb45d6 in doshfunc (shfunc=0x5643fd1ccea0, doshargs=doshargs@entry=0x0, noreturnval=noreturnval@entry=1) at ../../Src/exec.c:5824
#25 0x00005643fcc17a43 in callhookfunc (name=0x5643fcc23818 "zshexit", lnklst=0x0, arrayp=1, retval=0x0) at ../../Src/utils.c:1530
#26 0x00005643fcba6095 in zexit (val=<optimized out>, from_where=<optimized out>) at ../../Src/builtin.c:5810
#27 0x00007fb6d7fcecb4 in getbyte (do_keytmout=do_keytmout@entry=0, timeout=timeout@entry=0x0, full=full@entry=1) at ../../../Src/Zle/zle_main.c:904
#28 0x00007fb6d7fcdbc3 in getkeybuf (w=<optimized out>) at ../../../Src/Zle/zle_keymap.c:1676
#29 getkeymapcmd (km=0x5643fd1900f0, funcp=funcp@entry=0x7fff40138c68, strp=strp@entry=0x7fff40138c70) at ../../../Src/Zle/zle_keymap.c:1587
#30 0x00007fb6d7fcddae in getkeycmd () at ../../../Src/Zle/zle_keymap.c:1715
#31 0x00007fb6d7fcfed5 in zlecore () at ../../../Src/Zle/zle_main.c:1124
#32 0x00007fb6d7fd0dd0 in zleread (lp=<optimized out>, rp=<optimized out>, flags=<optimized out>, context=0, init=0x7fb6d7ff041d "zle-line-init", 
    finish=0x7fb6d7ff040d "zle-line-finish") at ../../../Src/Zle/zle_main.c:1347
#33 0x00005643fcbcbcb8 in zleentry (cmd=cmd@entry=1) at ../../Src/init.c:1604
#34 0x00005643fcbcd209 in inputline () at ../../Src/input.c:295
#35 ingetc () at ../../Src/input.c:228
#36 0x00005643fcbcd37f in ingetc () at ../../Src/input.c:196
#37 0x00005643fcbc4e66 in ihgetc () at ../../Src/hist.c:407
#38 0x00005643fcbd6a9e in gettok () at ../../Src/lex.c:611
#39 zshlex () at ../../Src/lex.c:275
#40 0x00005643fcbd787e in zshlex () at ../../Src/lex.c:268
#41 0x00005643fcbf6776 in parse_event (endtok=endtok@entry=37) at ../../Src/parse.c:581
#42 0x00005643fcbc8545 in loop (toplevel=toplevel@entry=1, justonce=justonce@entry=0) at ../../Src/init.c:147
#43 0x00005643fcbcc2c6 in zsh_main (argc=<optimized out>, argv=<optimized out>) at ../../Src/init.c:1758
#44 0x00007fb6d84da09b in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#45 0x00005643fcb90d4a in _start ()
```

Looking into `getbyte` in zle_main.c there's this code:

```c
r = raw_getbyte(do_keytmout, &cc, full);
…
if (r == 0) {
    /* The test for IGNOREEOF was added to make zsh ignore ^Ds
       that were typed while commands are running.  Unfortunately
       this caused trouble under at least one system (SunOS 4.1).
       Here shells that lost their xterm (e.g. if it was killed
       with -9) didn't fail to read from the terminal but instead
       happily continued to read EOFs, so that the above read
       returned with 0, and, with IGNOREEOF set, this caused
       an infinite loop.  The simple way around this was to add
       the counter (icnt) so that this happens 20 times and than
       the shell gives up (yes, this is a bit dirty...). */
    if ((zlereadflags & ZLRF_IGNOREEOF) && icnt++ < 20)
        continue;
    stopmsg = 1;
    zexit(1, ZEXIT_NORMAL);
}
```

So, if `raw_getbyte` returns `0` `zexit` gets called again. I think this
causes the loop. I didn't debug a hanging process. I've got the backtrace
from a core dump.

Regards Jörg

-- 
Jeder macht, was er will – Keiner macht was er soll – Aber alle machen mit!

Attachment: signature.asc
Description: PGP signature



Messages sorted by: Reverse Date, Date, Thread, Author