From: Philippe Waroquiers Date: Tue, 5 Feb 2019 22:47:53 +0000 (+0100) Subject: Fix GDB being suspended SIGTTOU when running gdb.multi/multi-arch-exec.exp X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=65d2b333a830b3f36c8b7ae9d9ed6c77f8be9270;p=binutils-gdb.git 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 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 * infrun.c (follow_exec): Call target_terminal::ours_for_output. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0b3ba3c785b..7cb9d8dee03 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,7 @@ +2019-03-28 Philippe Waroquiers + + * infrun.c (follow_exec): Call target_terminal::ours_for_output. + 2019-03-28 Sandra Loosemore * nios2-tdep.h (struct gdbarch_tdep): Add is_kernel_helper. diff --git a/gdb/infrun.c b/gdb/infrun.c index ad7892105a4..0cfa2d6825d 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.