[binutils-gdb] Fix GDB being suspended SIGTTOU when running gdb.multi/multi-arch-exec.exp

Philippe Waroquiers philippe@sourceware.org
Thu Mar 28 20:16:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=65d2b333a830b3f36c8b7ae9d9ed6c77f8be9270

commit 65d2b333a830b3f36c8b7ae9d9ed6c77f8be9270
Author: Philippe Waroquiers <philippe.waroquiers@skynet.be>
Date:   Tue Feb 5 23:47:53 2019 +0100

    Fix GDB being suspended SIGTTOU when running gdb.multi/multi-arch-exec.exp
    
    When running under valgrind, multi-arch-exec.exp blocks forever.
    Some (painful) investigation shows this is due to valgrind slowing
    down GDB, and GDB has to output some messages at a different time,
    when GDB does not have the terminal for output.
    
    To reproduce the problem, you need to slow down GDB.
    It can be reproduced by:
    cd gdb/testsuite/outputs/gdb.multi/multi-arch-exec/
    ../../../../gdb -ex 'set debug lin-lwp 1' -ex 'break all_started' -ex 'run' ./2-multi-arch-exec
    
    The above stops at a breakpoint.  Do continue.
    GDB is then suspended because of SIGTTOU.
    The stacktrace that leads to the hanging GDB is:
    (top-gdb) bt
        at ../../binutils-gdb/gdb/exceptions.c:130
    ....
    
    Alternatively, the same happens when doing
    strace -o s.out ../../../../gdb  -ex 'break all_started' -ex 'run' ./2-multi-arch-exec
    
    And of course, valgrind is also sufficiently slowing down GDB to
    reproduce this :).
    
    Fix this by calling target_terminal::ours_for_output ();
    at the beginning of follow_exec.
    
    Note that all this terminal handling is not very clear to me:
      * Some code takes the terminal, and then takes care to give it back to the inferior
        if the terminal was belonging to the inferior.
        (e.g. annotate_breakpoints_invalid).
      * some code takes the terminal, but does not give it back
        (e.g. update_inserted_breakpoint_locations).
      * some code takes it, and unconditionally gives it back
        (e.g. handle_jit_event)
      * here and there, we also find
        gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
        before a (sometimes optional) call to ours_for_output.
        And such calls to ours_for_output is sometimes protected by:
           if (target_supports_terminal_ours ())
        (e.g. exceptions.c: print_flush).
        but most of the code calls it without checking if the target supports it.
      * some code is outputting some errors, but only takes the terminal
        after. E.g. infcmd.c: prepare_one_step
    
    gdb/ChangeLog
    2019-03-28  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
    
    	* infrun.c (follow_exec): Call target_terminal::ours_for_output.

Diff:
---
 gdb/ChangeLog | 4 ++++
 gdb/infrun.c  | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0b3ba3c..7cb9d8d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,7 @@
+2019-03-28  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
+
+	* infrun.c (follow_exec): Call target_terminal::ours_for_output.
+
 2019-03-28  Sandra Loosemore  <sandra@codesourcery.com>
 
 	* nios2-tdep.h (struct gdbarch_tdep): Add is_kernel_helper.
diff --git a/gdb/infrun.c b/gdb/infrun.c
index ad78921..0cfa2d6 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1087,6 +1087,10 @@ follow_exec (ptid_t ptid, char *exec_file_target)
   int pid = ptid.pid ();
   ptid_t process_ptid;
 
+  /* Switch terminal for any messages produced e.g. by
+     breakpoint_re_set.  */
+  target_terminal::ours_for_output ();
+
   /* This is an exec event that we actually wish to pay attention to.
      Refresh our symbol table to the newly exec'd program, remove any
      momentary bp's, etc.



More information about the Gdb-cvs mailing list