File gdb-block-sigterm-during-fetch_inferior_event.patch of Package gdb

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

openSUSE Build Service is sponsored by