aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>2019-02-05 23:47:53 +0100
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>2019-03-28 21:14:14 +0100
commit65d2b333a830b3f36c8b7ae9d9ed6c77f8be9270 (patch)
tree407f87a029d380dcfa0ab6a27a76b69cc5b04a3c /gdb/infrun.c
parentf489207efde922e436b1b420d4de071927e3b9d5 (diff)
downloadgdb-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.c4
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.