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.
This commit is contained in:
Philippe Waroquiers 2019-02-05 23:47:53 +01:00
parent f489207efd
commit 65d2b333a8
2 changed files with 8 additions and 0 deletions

View File

@ -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.

View File

@ -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.