93 lines
3.2 KiB
Diff
93 lines
3.2 KiB
Diff
From 32a7b58de39da07e3449d90c31edb104e14480f1 Mon Sep 17 00:00:00 2001
|
|
From: Andrew Burgess <aburgess@redhat.com>
|
|
Date: Thu, 27 Feb 2025 11:31:02 +0000
|
|
Subject: [PATCH 2/5] gdb: block SIGTERM during fetch_inferior_event
|
|
|
|
I'm posting this as RFC. I started looking at this when I got a CI
|
|
failure email from Linaro about a regression on
|
|
gdb.base/gdb-sigerm.exp on ARM. Turns out is wasn't my fault, it's
|
|
just the precise failure point moves about, so it can look like a
|
|
regression.
|
|
|
|
After looking at it for a bit I realised this was PR gdb/31061, and
|
|
there have already been attempts to fix this over the last few years.
|
|
|
|
What I have here is different than any of the previous approaches
|
|
posted, but I'm still not entirely sure this is the right solution,
|
|
but I thought I'd share it. Might be nice to see if we can get this
|
|
fixed.
|
|
|
|
The patch might still need some cleanup, but it should be good enough
|
|
to discuss this approach.
|
|
|
|
Thanks,
|
|
Andrew
|
|
---
|
|
gdb/infrun.c | 36 ++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 36 insertions(+)
|
|
|
|
diff --git a/gdb/infrun.c b/gdb/infrun.c
|
|
index 8a10119487c..cdce1c0b6c2 100644
|
|
--- a/gdb/infrun.c
|
|
+++ b/gdb/infrun.c
|
|
@@ -78,6 +78,7 @@
|
|
#include "extension.h"
|
|
#include "disasm.h"
|
|
#include "interps.h"
|
|
+#include "gdbsupport/scoped_ignore_signal.h"
|
|
|
|
/* Prototypes for local functions */
|
|
|
|
@@ -4574,6 +4575,31 @@ infrun_quit_handler ()
|
|
}
|
|
}
|
|
|
|
+/* Block SIGTERM and then clear sync_quit_force_run. When we go out of
|
|
+ scope, restore the previous sync_quit_force_run value, and then unblock
|
|
+ signals.
|
|
+
|
|
+ This should maybe live in a support file somewhere, but it needs to see
|
|
+ sync_quit_force_run, so likely needs to live in the gdb/ directory. */
|
|
+
|
|
+struct scoped_ignore_sigterm
|
|
+{
|
|
+ scoped_ignore_sigterm ()
|
|
+ : m_old_val (sync_quit_force_run)
|
|
+ {
|
|
+ sync_quit_force_run = false;
|
|
+ }
|
|
+
|
|
+ ~scoped_ignore_sigterm ()
|
|
+ {
|
|
+ sync_quit_force_run = m_old_val;
|
|
+ }
|
|
+
|
|
+private:
|
|
+ scoped_ignore_signal<SIGTERM, false> m_ignore_signal;
|
|
+ bool m_old_val;
|
|
+};
|
|
+
|
|
/* Asynchronous version of wait_for_inferior. It is called by the
|
|
event loop whenever a change of state is detected on the file
|
|
descriptor corresponding to the target. It can be called more than
|
|
@@ -4609,6 +4635,16 @@ fetch_inferior_event ()
|
|
scoped_restore restore_quit_handler
|
|
= make_scoped_restore (&quit_handler, infrun_quit_handler);
|
|
|
|
+ /* Similar to how the above custom quit handler ignores the quit flag
|
|
+ (thus not interrupting GDB on receipt of Ctrl-C), this arranges to
|
|
+ block SIGTERM while we are handling the inferior event. Any SIGTERM
|
|
+ will be deferred until this function is done. Usually SIGTERM is
|
|
+ converted to an exception by the QUIT macro, but doing that while
|
|
+ processing an inferior event can leave the inferior in a weird state,
|
|
+ e.g. some breakpoints not removed. Deferring SIGTERM handling until
|
|
+ after this function means the event should have been fully handled. */
|
|
+ scoped_ignore_sigterm ignore_sigterm;
|
|
+
|
|
/* Make sure a SIGINT does not interrupt an extension language while
|
|
we're handling an event. That could interrupt a Python unwinder
|
|
or a Python observer or some such. A Ctrl-C should either be
|
|
--
|
|
2.43.0
|
|
|