public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Kevin Buettner <kevinb@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH v2 2/6] Handle gdb SIGTERM via normal QUIT processing
Date: Sun, 22 Aug 2021 16:19:58 -0700	[thread overview]
Message-ID: <20210822231959.184061-3-kevinb@redhat.com> (raw)
In-Reply-To: <20210822231959.184061-1-kevinb@redhat.com>

When a GDB process receives the SIGTERM signal, handle_sigterm() in
event-top.c is called.  The global variable "sync_quit_force_run" is
set by this signal handler.  (It does some other things too, but the
setting of this global is the important bit for the SIGTERM part of
this discussion.)

GDB will periodically check to see whether a Ctrl-C or SIGTERM has
been received.  This is indicated via use of the QUIT macro in
GDB's code.  QUIT is defined to invoke maybe_quit(), which will be
periodically called during any lengthy operation.  This ensures that
the user won't have to wait too long for a Ctrl-C or SIGTERM to be
acted upon.

When a Ctrl-C / SIGINT is received, quit_handler() will decide
whether to pass the SIGINT onto the inferior or to call quit()
which (eventually) causes gdb_exception_quit to be thrown.  This
exception (usually) propagates to the top level.  At that point,
exception_print() is called to print the exception.  Control
is then returned to the top level event loop.

At the moment, SIGTERM is handled very differently.  Instead of
throwing an exception, quit_force() is called.  This does eventually
cause GDB to exit(), but prior to that happening, the inferiors
are killed or detached and other target related cleanup occurs.
As shown in this discussion between Pedro Alves and myself...

https://sourceware.org/pipermail/gdb-patches/2021-July/180802.html
https://sourceware.org/pipermail/gdb-patches/2021-July/180902.html
https://sourceware.org/pipermail/gdb-patches/2021-July/180903.html

...we found that it is possible for inferior_ptid and current_thread_
to get out of sync.  When that happens, the "current_thread_ != nullptr"
assertion in inferior_thread() can fail resulting in a GDB internal
error.

Pedro recommended that we "let the normal quit exception propagate all
the way to the top level, and then have the top level call quit_force
if sync_quit_force_run is set."

This commit implements the obvious part of Pedro's suggestion:
Instead of calling quit_force from quit(), throw_quit() is now called
instead.  We leave sync_quit_force set for interrogation at a higher
level.

At the top level, I found that the first thing done in each catch
block is to call exception_print().  Thus I placed a check to
see whether sync_quit_force is set within exception_print().  When
it's set, quit_force() will be called.

Making these changes fixed the failure / regression that I was seeing
for gdb.base/gdb-sigterm.exp when run on a machine with glibc-2.34.
However, there are many other paths back to the top level which this
test case does not test.  It seemed likely to me that some catch
blocks might swallow a QUIT, not allowing it to get to the top level.
The rest of the patches in this series deal with this concern.
---
 gdb/exceptions.c | 6 ++++++
 gdb/utils.c      | 5 +----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/gdb/exceptions.c b/gdb/exceptions.c
index 32db6fe8235..d3b15dd6320 100644
--- a/gdb/exceptions.c
+++ b/gdb/exceptions.c
@@ -108,6 +108,12 @@ print_exception (struct ui_file *file, const struct gdb_exception &e)
 void
 exception_print (struct ui_file *file, const struct gdb_exception &e)
 {
+  if (sync_quit_force_run)
+    {
+      sync_quit_force_run = 0;
+      quit_force (NULL, 0);
+    }
+
   if (e.reason < 0 && e.message != NULL)
     {
       print_flush ();
diff --git a/gdb/utils.c b/gdb/utils.c
index c59c63565eb..971302ced16 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -624,10 +624,7 @@ void
 quit (void)
 {
   if (sync_quit_force_run)
-    {
-      sync_quit_force_run = 0;
-      quit_force (NULL, 0);
-    }
+    throw_quit ("SIGTERM Quit");
 
 #ifdef __MSDOS__
   /* No steenking SIGINT will ever be coming our way when the
-- 
2.31.1


  parent reply	other threads:[~2021-08-22 23:23 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-22 23:19 [PATCH v2 0/6] glibc-2.34: Fix gdb.base/gdb-sigterm.exp failure/error Kevin Buettner
2021-08-22 23:19 ` [PATCH v2 1/6] Handle recursive internal problem in gdb_internal_error_resync Kevin Buettner
2021-09-27 17:38   ` Pedro Alves
2022-02-26 20:40     ` Kevin Buettner
2021-08-22 23:19 ` Kevin Buettner [this message]
2021-09-27 17:39   ` [PATCH v2 2/6] Handle gdb SIGTERM via normal QUIT processing Pedro Alves
2021-08-22 23:20 ` [PATCH v2 3/6] Catch and (re)throw gdb_exception_quit Kevin Buettner
2021-09-27 18:05   ` Pedro Alves
2021-08-22 23:20 ` [PATCH v2 4/6] Python QUIT processing updates Kevin Buettner
2021-09-27 18:24   ` Pedro Alves
2021-08-22 23:20 ` [PATCH v2 5/6] Guile " Kevin Buettner
2021-09-27 18:26   ` Pedro Alves
2021-08-22 23:20 ` [PATCH v2 6/6] QUIT processing w/ explicit sync_quit_force_run check Kevin Buettner
2021-09-27 18:34   ` Pedro Alves
2021-09-27 17:20 ` [PATCH v2 0/6] glibc-2.34: Fix gdb.base/gdb-sigterm.exp failure/error Kevin Buettner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210822231959.184061-3-kevinb@redhat.com \
    --to=kevinb@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).