Fix signal unsafe call inside a signal
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Testing passed
|
Commit Message
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 | 13 ++++++++---
gdb/event-top.c | 58 +++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 61 insertions(+), 10 deletions(-)
Comments
On Mai 21 2024, Bernd Edlinger wrote:
> diff --git a/gdb/bt-utils.c b/gdb/bt-utils.c
> index f658ce0d4bc..c5d266a0cac 100644
> --- a/gdb/bt-utils.c
> +++ b/gdb/bt-utils.c
> @@ -125,6 +125,8 @@ gdb_internal_backtrace_1 ()
>
> /* See the comment on previous version of this function. */
>
> +static str_backtrace_incomplete = _("Backtrace might be incomplete.\n");
That calls gettext in a static constructor, which runs before the locale
is set.
@@ -125,6 +125,8 @@ gdb_internal_backtrace_1 ()
/* See the comment on previous version of this function. */
+static str_backtrace_incomplete = _("Backtrace might be incomplete.\n");
+
static void
gdb_internal_backtrace_1 ()
{
@@ -139,7 +141,7 @@ 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
@@ -149,6 +151,11 @@ gdb_internal_backtrace_1 ()
/* See bt-utils.h. */
+#ifdef GDB_PRINT_INTERNAL_BACKTRACE
+static const char *str_backtrace = _("----- Backtrace -----\n");
+static const char *str_backtrace_unavailable = _("Backtrace unavailable\n");
+#endif
+
void
gdb_internal_backtrace ()
{
@@ -161,12 +168,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
@@ -891,6 +891,29 @@ unblock_signal (int sig)
return false;
}
+/* Signal safe language specific strings. */
+
+#ifdef GDB_PRINT_INTERNAL_BACKTRACE
+static const char *str_fatal_signal = _("Fatal signal: ");
+static const char *str_sigsegv = strsignal(SIGSEGV);
+#ifdef SIGFPE
+static const char *str_sigfpe = strsignal(SIGFPE);
+#endif
+#ifdef SIGBUS
+static const char *str_sigbus = strsignal(SIGBUS);
+#endif
+#ifdef SIGABRT
+static const char *str_sigabrt = strsignal(SIGABRT);
+#endif
+static const char *str_unknown_signal = _("Unknown signal");
+static const char *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");
+static const char *str_this_is_a_bug = _("This is a bug, please report it.");
+static const char *str_for_instructions_see = _(" For instructions, see:\n");
+#endif
+
/* Called to handle fatal signals. SIG is the signal number. */
static void ATTRIBUTE_NORETURN
@@ -909,19 +932,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 (".");
}