aboutsummaryrefslogtreecommitdiff
path: root/gdb/inflow.c
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@polymtl.ca>2018-10-23 17:00:33 -0400
committerSimon Marchi <simon.marchi@polymtl.ca>2018-10-23 17:00:41 -0400
commit35ed81d4f45855b98ea0c517b396662c3ae2a8c5 (patch)
treed951fce7a94115862b6cd7f6bfc700399ace8610 /gdb/inflow.c
parent79b8d3b090bcbfbcffa8bdd195476c6db172273b (diff)
downloadgdb-35ed81d4f45855b98ea0c517b396662c3ae2a8c5.zip
gdb-35ed81d4f45855b98ea0c517b396662c3ae2a8c5.tar.gz
gdb-35ed81d4f45855b98ea0c517b396662c3ae2a8c5.tar.bz2
Avoid GDB SIGTTOU on catch exec + set follow-exec-mode new (PR 23368)
Here's a summary of PR 23368: #include <unistd.h> int main (void) { char *exec_args[] = { "/bin/ls", NULL }; execve (exec_args[0], exec_args, NULL); } $ gdb -nx t -ex "catch exec" -ex "set follow-exec-mode new" -ex run ... [1] + 13146 suspended (tty output) gdb -q -nx t -ex "catch exec" -ex "set follow-exec-mode new" -ex run $ Here's what happens: when the inferior execs with "follow-exec-mode new", we first "mourn" it before creating the new one. This ends up calling inflow_inferior_exit, which sets the per-inferior terminal state to "is_ours": inf->terminal_state = target_terminal_state::is_ours; At this point, the inferior's terminal_state is is_ours, while the "reality", tracked by gdb_tty_state, is is_inferior (GDB doesn't own the terminal). Later, we continue processing the exec inferior event and decide we want to stop (because of the "catch exec") and call target_terminal::ours to make sure we own the terminal. However, we don't actually go to the target backend to change the settings, because the core thinks that no inferior owns the terminal (inf->terminal_state is target_terminal_state::is_ours, as checked in target_terminal_is_ours_kind, for both inferiors). When something in readline tries to mess with the terminal settings, it generates a SIGTTOU. This patch fixes this by tranferring the state of the terminal from the old inferior to the new inferior. gdb/ChangeLog: PR gdb/23368 * infrun.c (follow_exec): In the follow_exec_mode_new case, transfer terminal state from old new new inferior. * terminal.h (swap_terminal_info): New function. * inflow.c (swap_terminal_info): New function.
Diffstat (limited to 'gdb/inflow.c')
-rw-r--r--gdb/inflow.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/gdb/inflow.c b/gdb/inflow.c
index caff646..a0c1c7d 100644
--- a/gdb/inflow.c
+++ b/gdb/inflow.c
@@ -702,6 +702,22 @@ copy_terminal_info (struct inferior *to, struct inferior *from)
to->terminal_state = from->terminal_state;
}
+/* See terminal.h. */
+
+void
+swap_terminal_info (inferior *a, inferior *b)
+{
+ terminal_info *info_a
+ = (terminal_info *) inferior_data (a, inflow_inferior_data);
+ terminal_info *info_b
+ = (terminal_info *) inferior_data (a, inflow_inferior_data);
+
+ set_inferior_data (a, inflow_inferior_data, info_b);
+ set_inferior_data (b, inflow_inferior_data, info_a);
+
+ std::swap (a->terminal_state, b->terminal_state);
+}
+
void
info_terminal_command (const char *arg, int from_tty)
{