[2/2] Demangler crash handler
Commit Message
This patch wraps calls to the demangler with a segmentation fault
handler. A warning is printed the first time a segmentation fault
is caught.
gdb/
2014-05-09 Gary Benson <gbenson@redhat.com>
PR backtrace/16817
* cp-support.c (signal.h): New include.
(gdb_demangle_signal_handler): New function.
(gdb_demangle): Install the above signal handler before calling
bfd_demangle, and restore the original signal handler afterwards.
gdb/testsuite/
2014-05-09 Gary Benson <gbenson@redhat.com>
PR backtrace/16817
* gdb.base/pr16817.exp: New file.
@@ -36,6 +36,7 @@
#include "value.h"
#include "cp-abi.h"
#include "language.h"
+#include <signal.h>
#include "safe-ctype.h"
@@ -1505,12 +1506,71 @@ cp_lookup_rtti_type (const char *name, struct block *block)
return rtti_type;
}
+/* Signal handler for gdb_demangle. */
+
+static void
+gdb_demangle_signal_handler (int signo)
+{
+ throw_error (GENERIC_ERROR, _("demangler failed with signal %d"),
+ signo);
+}
+
/* A wrapper for bfd_demangle. */
char *
gdb_demangle (const char *name, int options)
{
- return bfd_demangle (NULL, name, options);
+ char *result = NULL;
+
+#ifdef SIGSEGV
+ volatile struct gdb_exception except;
+
+#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
+ struct sigaction sa, old_sa;
+
+ sa.sa_handler = gdb_demangle_signal_handler;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction (SIGSEGV, &sa, &old_sa);
+#else
+ void (*ofunc) ();
+
+ ofunc = (void (*)()) signal (SIGSEGV, gdb_demangle_signal_handler);
+#endif
+#endif
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ result = bfd_demangle (NULL, name, options);
+ }
+
+#ifdef SIGSEGV
+#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
+ sigaction (SIGSEGV, &old_sa, NULL);
+#else
+ signal (SIGSEGV, ofunc);
+#endif
+#endif
+
+ if (except.reason < 0)
+ {
+ static int warning_printed = 0;
+
+ if (!warning_printed)
+ {
+ warning ("internal error: %s\n"
+ "Unable to demangle '%s'\n"
+ "This is a bug, "
+ "please report it to the GDB maintainers.",
+ except.message, name);
+
+ warning_printed = 1;
+ }
+
+ result = NULL;
+ }
+
+ return result;
}
/* Don't allow just "maintenance cplus". */
new file mode 100644
@@ -0,0 +1,25 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test that a segmentation fault in the demangler does not cause GDB
+# to crash. If the demangler becomes able to demangle the below
+# symbol then another symbol will need to be found for this test.
+
+set symbol "_QueueNotification_QueueController__\$4PPPPPPPM_A_INotice___Z"
+
+gdb_exit
+gdb_start
+gdb_test_no_output "set lang c++"
+gdb_test "maint demangle $symbol" ".*demangler failed.*"