diff options
author | Philippe Waroquiers <philippe.waroquiers@skynet.be> | 2019-02-05 23:47:53 +0100 |
---|---|---|
committer | Philippe Waroquiers <philippe.waroquiers@skynet.be> | 2019-03-28 21:14:14 +0100 |
commit | 65d2b333a830b3f36c8b7ae9d9ed6c77f8be9270 (patch) | |
tree | 407f87a029d380dcfa0ab6a27a76b69cc5b04a3c /gdb/infrun.c | |
parent | f489207efde922e436b1b420d4de071927e3b9d5 (diff) | |
download | gdb-65d2b333a830b3f36c8b7ae9d9ed6c77f8be9270.zip gdb-65d2b333a830b3f36c8b7ae9d9ed6c77f8be9270.tar.gz gdb-65d2b333a830b3f36c8b7ae9d9ed6c77f8be9270.tar.bz2 |
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.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 4 |
1 files changed, 4 insertions, 0 deletions
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. |