From 8ac39635f6f0b7019f4a474f995e94d447fe8d38 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Wed, 7 Aug 2019 18:23:49 +0200 Subject: [PATCH] Suppress SIGTTOU when handling errors [ Backport of commit 766f883622. ] Calls to error () can cause SIGTTOU to send gdb to the background. For example, on an Arm build: (gdb) b main Breakpoint 1 at 0x10774: file /build/gdb/testsuite/../../../src/binutils-gdb/gdb/testsuite/gdb.base/watchpoint.c, line 174. (gdb) r Starting program: /build/gdb/testsuite/outputs/gdb.base/watchpoint/watchpoint [1]+ Stopped ../gdb ./outputs/gdb.base/watchpoint/watchpoint localhost$ fg ../gdb ./outputs/gdb.base/watchpoint/watchpoint Cannot parse expression `.L1199 4@r4'. warning: Probes-based dynamic linker interface failed. Reverting to original interface. The SIGTTOU is raised whilst inside a syscall during the call to tcdrain. Fix is to use scoped_ignore_sigttou to ensure SIGTTOU is blocked. In addition fix include comments - job_control is not included via terminal.h gdb/ChangeLog: * event-top.c: Remove include comment. * inflow.c (class scoped_ignore_sigttou): Move from here... * inflow.h (class scoped_ignore_sigttou): ...to here. * ser-unix.c (hardwire_drain_output): Block SIGTTOU during drain. * top.c: Remove include comment. --- gdb/ChangeLog | 8 ++++++++ gdb/event-top.c | 2 +- gdb/inflow.c | 29 ----------------------------- gdb/inflow.h | 31 +++++++++++++++++++++++++++++++ gdb/ser-unix.c | 4 ++++ gdb/top.c | 2 +- 6 files changed, 45 insertions(+), 31 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f101a27be53..c8ddcf6f2e6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2019-05-28 Alan Hayward + + * event-top.c: Remove include comment. + * inflow.c (class scoped_ignore_sigttou): Move from here... + * inflow.h (class scoped_ignore_sigttou): ...to here. + * ser-unix.c (hardwire_drain_output): Block SIGTTOU during drain. + * top.c: Remove include comment. + 2019-08-04 Alan Hayward * symfile.c (symbol_file_command): Call solib_create_inferior_hook. diff --git a/gdb/event-top.c b/gdb/event-top.c index fb5d51c6e10..e077e29ba05 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -24,7 +24,7 @@ #include "inferior.h" #include "infrun.h" #include "target.h" -#include "terminal.h" /* for job_control */ +#include "terminal.h" #include "event-loop.h" #include "event-top.h" #include "interps.h" diff --git a/gdb/inflow.c b/gdb/inflow.c index b71511308b3..c1f26939929 100644 --- a/gdb/inflow.c +++ b/gdb/inflow.c @@ -103,35 +103,6 @@ static serial_ttystate initial_gdb_ttystate; static struct terminal_info *get_inflow_inferior_data (struct inferior *); -/* RAII class used to ignore SIGTTOU in a scope. */ - -class scoped_ignore_sigttou -{ -public: - scoped_ignore_sigttou () - { -#ifdef SIGTTOU - if (job_control) - m_osigttou = signal (SIGTTOU, SIG_IGN); -#endif - } - - ~scoped_ignore_sigttou () - { -#ifdef SIGTTOU - if (job_control) - signal (SIGTTOU, m_osigttou); -#endif - } - - DISABLE_COPY_AND_ASSIGN (scoped_ignore_sigttou); - -private: -#ifdef SIGTTOU - sighandler_t m_osigttou = NULL; -#endif -}; - /* While the inferior is running, we want SIGINT and SIGQUIT to go to the inferior only. If we have job control, that takes care of it. If not, we save our handlers in these two variables and set SIGINT and SIGQUIT diff --git a/gdb/inflow.h b/gdb/inflow.h index c32aa144331..5dd5c37bd2b 100644 --- a/gdb/inflow.h +++ b/gdb/inflow.h @@ -21,5 +21,36 @@ #define INFLOW_H #include +#include +#include "common/job-control.h" + +/* RAII class used to ignore SIGTTOU in a scope. */ + +class scoped_ignore_sigttou +{ +public: + scoped_ignore_sigttou () + { +#ifdef SIGTTOU + if (job_control) + m_osigttou = signal (SIGTTOU, SIG_IGN); +#endif + } + + ~scoped_ignore_sigttou () + { +#ifdef SIGTTOU + if (job_control) + signal (SIGTTOU, m_osigttou); +#endif + } + + DISABLE_COPY_AND_ASSIGN (scoped_ignore_sigttou); + +private: +#ifdef SIGTTOU + sighandler_t m_osigttou = NULL; +#endif +}; #endif /* inflow.h */ diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c index 5a9965bf744..3492619f2d6 100644 --- a/gdb/ser-unix.c +++ b/gdb/ser-unix.c @@ -32,6 +32,7 @@ #include "gdbcmd.h" #include "common/filestuff.h" #include +#include "inflow.h" struct hardwire_ttystate { @@ -164,6 +165,9 @@ hardwire_print_tty_state (struct serial *scb, static int hardwire_drain_output (struct serial *scb) { + /* Ignore SIGTTOU which may occur during the drain. */ + scoped_ignore_sigttou ignore_sigttou; + return tcdrain (scb->fd); } diff --git a/gdb/top.c b/gdb/top.c index acc67202b64..00e0791a2dd 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -34,7 +34,7 @@ #include "expression.h" #include "value.h" #include "language.h" -#include "terminal.h" /* For job_control. */ +#include "terminal.h" #include "common/job-control.h" #include "annotate.h" #include "completer.h" -- 2.39.5