#545 mt/readline: terminal is left raw on crash

lisp error
closed-fixed
Sam Steingold
5
2010-04-15
2010-04-12
Sam Steingold
No

when clisp (cvs head) is built with MT & readline, killing clisp leaves the terminal in the raw state:
1. start clisp (built with MT & readline) in a terminal, wait for the "[1]> " prompt.
2, type "killall -v lisp.run" in a separate terminal.
3. return to the first terminal to discover the message "*** some threads were not signaled to terminate." and a raw terminal.

Discussion

1 2 > >> (Page 1 of 2)
  • This bug report is now marked as "pending"/"works for me".
    This means that we think that we cannot reproduce the problem
    and cannot do anything about it.
    Unless you - the reporter - act within 2 weeks
    (e.g., by submitting a self-contained test case
    or answering our other recent requests),
    the bug will be permanently closed.
    Sorry about the inconvenience -
    we hope your silence means that
    you are no longer observing the problem either.

     
  • The erroneous message "** some threads were not signaled to terminate." should be gone in the cvs.
    My observation so far: http://article.gmane.org/gmane.lisp.clisp.devel/21456
    The steps above do not reproduce the problem on my Ubuntu machine (Linux vtz 2.6.27-11-generic #1 SMP Thu Jan 29 19:24:39 UTC 2009 i686 GNU/Linux). That's not to say there is no problem - I experienced it few times (after I started to build with libreadline).

     
  • Sam Steingold
    Sam Steingold
    2010-04-12

    quit() is not called from signal_handler_thread() when terminating.
    maybe fini_lowest_level() should at least be called?

     
  • this is the standard request for more information.
    1. what is your platform?
    ("uname -a" on a Unix system)
    compiler version? libc (on Linux)?
    2. where did you get the sources? when?
    (absolute dates are prefered over the relative ones)
    3. how did you build CLISP? (what command, options &c)
    please do a clean build (remove your build directory and
    build CLISP with "./configure --build build" or at least
    do a "make distclean" before "make")
    4. if you are using pre-built binaries, the problem is likely
    to be in the incompatibilities between the platform on which
    the binary was built and yours;
    please try compiling the sources.
    5. what is the output of (lisp-implementation-version)?
    6. what is the value of *features*?
    7. please supply the full output (copy and paste)
    of all the error messages.
    If you cannot build CLISP, you can obviously skip 5 and 6,
    but then you should provide more information in 1.
    please see <http://clisp.cons.org/clisp.html#bugs>
    for more information.
    Thanks.

    PS. This bug report is now marked "pending"
    and will auto-close unless you respond
    (in which case it will auto-re-open).

     
  • quit() is called when the last thread in the process exits (see delete_thread()).
    I guess the problem is either with libreadline itself (not thread safe) or some race between threads when changing terminal_raw variable (in stream.d).
    Can you try to replace terminal_sane() with following (always call term_unraw() regardless of terminal_raw value):
    global void terminal_sane (void) {
    term_unraw();
    terminal_raw = false;
    }

     
  • Sam Steingold
    Sam Steingold
    2010-04-13

    I can no longer reliably reproduce this.
    when I add a "printf("terminal_sane(%d)\n",terminal_raw);" to the beginning of terminal_sane(), I see this:

    $ ./clisp -q -norc -K boot
    STACK size: 98222 [0x2ba52d4e5e00 0x2ba52d426090]
    [1]> (make-thread (lambda () (sleep 100)))
    #<THREAD :LAMBDA>
    [2]> (make-thread (lambda () (y-or-n-p "foo?")))
    #<THREAD :LAMBDA>
    [3]>
    foo? (y/n) (make-thread (lambda () (y-or-n-p "foo?")))
    #<THREAD :LAMBDA>
    [4]>
    foo? (y/n) (make-thread (lambda () (y-or-n-p "foo?")))
    Please answer with y or n : (make-thread (lambda () (y-or-n-p "foo?")))
    #<THREAD :LAMBDA>
    [5]>
    foo? (y/n) (make-thread (lambda () (y-or-n-p "foo?")))
    Please answer with y or n : (make-thread (lambda () (y-or-n-p "foo?")))
    Please answer with y or n : Exiting on signal 15

    terminal_sane(0)
    Terminated

    when I do "killall -v lisp.run" in a different window.

     
  • By reading libreadline source I found following in signals.c:

    /* Exported variables for use by applications. */

    /* If non-zero, readline will install its own signal handlers for
    SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
    int rl_catch_signals = 1;

    /* If non-zero, readline will install a signal handler for SIGWINCH. */
    #ifdef SIGWINCH
    int rl_catch_sigwinch = 1;
    #else
    int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
    #endif

    Looks like libreadline installs it's own signal handlers by default. This (esp. SIGALRM - used for timeout calls) for sure interferes with clisp signal handling (in some undefined way).

    I guess disabling this (rl_catch_signals = 0, rl_catch_sigwinch = 0) may fix the problem. Bu also I do not know what consequences this will have on readline behavior.

     
  • Sam Steingold
    Sam Steingold
    2010-04-15

    yay! I can reproduce this again!
    $ cd tests ; make clean mt.erg compare ; cd -
    [wait for y-or-n-p-timeout tests, switch to a different console, type "killall -v lisp.run" there]
    and observe
    Exiting on signal 15
    ...
    Bye.
    make: *** [mt.erg] Terminated
    make: *** Deleting file `mt.erg'

    and a raw terminal (requires "reset")

    note that adding "rl_catch_signals = 0;" to make_terminal_stream_() :

    --- stream.d.~1.675.~ 2010-03-18 10:48:19.000000000 -0400
    +++ stream.d 2010-04-15 11:35:43.001954000 -0400
    @@ -10005,6 +10005,9 @@ local maygc object make_terminal_stream_
    var bool same_tty = stdin_tty && stdout_tty && stdio_same_tty_p();
    end_system_call();
    #ifdef HAVE_TERMINAL3
    + #ifdef MULTITHREAD
    + rl_catch_signals = 0;
    + #endif
    if (rl_gnu_readline_p && same_tty && !disable_readline) { /* Build a TERMINAL3-Stream: */
    pushSTACK(make_ssstring(80)); /* allocate line-buffer */
    pushSTACK(make_ssstring(80)); /* allocate line-buffer */

    which is called _before_ rl_set_signals(),
    does _NOT_ fix the problem, i.e., I still get the raw terminal.

     
  • Sam Steingold
    Sam Steingold
    2010-04-15

    • milestone: 100335 --> 1107844
     
  • Sam Steingold
    Sam Steingold
    2010-04-15

    • labels: 100543 --> multithreading
    • milestone: 1107844 --> lisp error
     
1 2 > >> (Page 1 of 2)