From: Bernd Edlinger <bernd.edlinger@hotmail.de>
To: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>,
Andrew Burgess <aburgess@redhat.com>
Subject: [PATCH v3] Fix signal unsafe call inside a signal
Date: Mon, 24 Jun 2024 17:30:36 +0200 [thread overview]
Message-ID: <AS8P193MB1285F1FB05AE08EC0C63763CE4D42@AS8P193MB1285.EURP193.PROD.OUTLOOK.COM> (raw)
As mentioned in
https://sourceware.org/bugzilla/show_bug.cgi?id=31713#c9
it can easily happen that the signal handler function
handle_fatal_signal() uses various signal unsafe functions.
Fix that by pre-computing the necessary language specific
strings.
---
gdb/bt-utils.c | 24 ++++++++++++--
gdb/bt-utils.h | 4 +++
gdb/event-top.c | 84 ++++++++++++++++++++++++++++++++++++++++++++-----
gdb/main.c | 4 +++
4 files changed, 106 insertions(+), 10 deletions(-)
v2: moved initalization of language specific string to an init function
v3: addressed review comments
diff --git a/gdb/bt-utils.c b/gdb/bt-utils.c
index f658ce0d4bc..787f425625c 100644
--- a/gdb/bt-utils.c
+++ b/gdb/bt-utils.c
@@ -123,6 +123,8 @@ gdb_internal_backtrace_1 ()
#elif defined GDB_PRINT_INTERNAL_BACKTRACE_USING_EXECINFO
+static const char *str_backtrace_incomplete;
+
/* See the comment on previous version of this function. */
static void
@@ -139,12 +141,28 @@ gdb_internal_backtrace_1 ()
backtrace_symbols_fd (buffer, frames, gdb_stderr->fd ());
if (frames == ARRAY_SIZE (buffer))
- sig_write (_("Backtrace might be incomplete.\n"));
+ sig_write (str_backtrace_incomplete);
}
#else
#error "unexpected internal backtrace policy"
#endif
+
+static const char *str_backtrace;
+static const char *str_backtrace_unavailable;
+
+/* Initialize language specific strings. */
+
+void
+init_str_internal_backtrace ()
+{
+ str_backtrace = _("----- Backtrace -----\n");
+ str_backtrace_unavailable = _("Backtrace unavailable\n");
+#ifdef GDB_PRINT_INTERNAL_BACKTRACE_USING_EXECINFO
+ str_backtrace_incomplete = _("Backtrace might be incomplete.\n");
+#endif
+}
+
#endif /* GDB_PRINT_INTERNAL_BACKTRACE */
/* See bt-utils.h. */
@@ -161,12 +179,12 @@ gdb_internal_backtrace ()
gdb_stderr->write_async_safe (msg, strlen (msg));
};
- sig_write (_("----- Backtrace -----\n"));
+ sig_write (str_backtrace);
if (gdb_stderr->fd () > -1)
gdb_internal_backtrace_1 ();
else
- sig_write (_("Backtrace unavailable\n"));
+ sig_write (str_backtrace_unavailable);
sig_write ("---------------------\n");
#endif
diff --git a/gdb/bt-utils.h b/gdb/bt-utils.h
index ec2d14a5484..b6a7ef5464d 100644
--- a/gdb/bt-utils.h
+++ b/gdb/bt-utils.h
@@ -71,4 +71,8 @@ extern void gdb_internal_backtrace ();
extern void gdb_internal_backtrace_set_cmd (const char *args, int from_tty,
cmd_list_element *c);
+#ifdef GDB_PRINT_INTERNAL_BACKTRACE
+extern void init_str_internal_backtrace ();
+#endif
+
#endif /* BT_UTILS_H */
diff --git a/gdb/event-top.c b/gdb/event-top.c
index b81970d11bb..1ef2eacfe94 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -892,6 +892,51 @@ unblock_signal (int sig)
return false;
}
+/* Signal safe language specific strings. */
+
+#ifdef GDB_PRINT_INTERNAL_BACKTRACE
+static const char *str_fatal_signal;
+static const char *str_sigsegv;
+#ifdef SIGFPE
+static const char *str_sigfpe;
+#endif
+#ifdef SIGBUS
+static const char *str_sigbus;
+#endif
+#ifdef SIGABRT
+static const char *str_sigabrt;
+#endif
+static const char *str_unknown_signal;
+static const char *str_fatal_error_detected_gdb_will_now_terminate;
+static const char *str_this_is_a_bug;
+static const char *str_for_instructions_see;
+
+/* Initialize language specific strings. */
+
+static void
+init_str_handle_fatal_signal ()
+{
+ str_fatal_signal = _("Fatal signal: ");
+ str_sigsegv = strsignal (SIGSEGV);
+#ifdef SIGFPE
+ str_sigfpe = strsignal (SIGFPE);
+#endif
+#ifdef SIGBUS
+ str_sigbus = strsignal (SIGBUS);
+#endif
+#ifdef SIGABRT
+ str_sigabrt = strsignal (SIGABRT);
+#endif
+ str_unknown_signal = _("Unknown signal");
+ str_fatal_error_detected_gdb_will_now_terminate =
+ _("A fatal error internal to GDB has been detected, "
+ "further\ndebugging is not possible. GDB will now "
+ "terminate.\n\n");
+ str_this_is_a_bug = _("This is a bug, please report it.");
+ str_for_instructions_see = _(" For instructions, see:\n");
+}
+#endif
+
/* Called to handle fatal signals. SIG is the signal number. */
static void ATTRIBUTE_NORETURN
@@ -910,19 +955,40 @@ handle_fatal_signal (int sig)
if (bt_on_fatal_signal)
{
sig_write ("\n\n");
- sig_write (_("Fatal signal: "));
- sig_write (strsignal (sig));
+ sig_write (str_fatal_signal);
+ switch (sig)
+ {
+ case SIGSEGV:
+ sig_write (str_sigsegv);
+ break;
+#ifdef SIGFPE
+ case SIGFPE:
+ sig_write (str_sigfpe);
+ break;
+#endif
+#ifdef SIGBUS
+ case SIGBUS:
+ sig_write (str_sigbus);
+ break;
+#endif
+#ifdef SIGABRT
+ case SIGABRT:
+ sig_write (str_sigabrt);
+ break;
+#endif
+ default:
+ sig_write (str_unknown_signal);
+ break;
+ }
sig_write ("\n");
gdb_internal_backtrace ();
- sig_write (_("A fatal error internal to GDB has been detected, "
- "further\ndebugging is not possible. GDB will now "
- "terminate.\n\n"));
- sig_write (_("This is a bug, please report it."));
+ sig_write (str_fatal_error_detected_gdb_will_now_terminate);
+ sig_write (str_this_is_a_bug);
if (REPORT_BUGS_TO[0] != '\0')
{
- sig_write (_(" For instructions, see:\n"));
+ sig_write (str_for_instructions_see);
sig_write (REPORT_BUGS_TO);
sig_write (".");
}
@@ -1050,6 +1116,10 @@ gdb_init_signals (void)
create_async_signal_handler (async_sigtstp_handler, NULL, "sigtstp");
#endif
+#ifdef GDB_PRINT_INTERNAL_BACKTRACE
+ init_str_handle_fatal_signal ();
+#endif
+
#ifdef SIGFPE
signal (SIGFPE, handle_fatal_signal);
#endif
diff --git a/gdb/main.c b/gdb/main.c
index 4dd68f3d976..213490e419c 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -58,6 +58,7 @@
#include "observable.h"
#include "serial.h"
#include "cli-out.h"
+#include "bt-utils.h"
/* The selected interpreter. */
std::string interpreter_p;
@@ -676,6 +677,9 @@ captured_main_1 (struct captured_main_args *context)
/* Note: `error' cannot be called before this point, because the
caller will crash when trying to print the exception. */
main_ui = new ui (stdin, stdout, stderr);
+#ifdef GDB_PRINT_INTERNAL_BACKTRACE
+ init_str_internal_backtrace ();
+#endif
current_ui = main_ui;
gdb_stdtarg = gdb_stderr;
--
2.39.2
reply other threads:[~2024-06-24 15:28 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=AS8P193MB1285F1FB05AE08EC0C63763CE4D42@AS8P193MB1285.EURP193.PROD.OUTLOOK.COM \
--to=bernd.edlinger@hotmail.de \
--cc=aburgess@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).