public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Gary Benson <gbenson@redhat.com>
To: Mark Kettenis <mark.kettenis@xs4all.nl>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH 0/2] Demangler crash handler
Date: Fri, 09 May 2014 15:33:00 -0000	[thread overview]
Message-ID: <20140509153305.GA13345@blade.nx> (raw)
In-Reply-To: <201405091120.s49BKO1f010622@glazunov.sibelius.xs4all.nl>

Mark Kettenis wrote:
> > A number of bugs have been filed recently because of segmentation
> > faults in the demangler.  While such crashes are a problem for all
> > demangler consumers, they are particularly nasty for GDB because
> > they prevent the user from debugging their program at all.
> > 
> > This patch series arranges for GDB to catch segmentation faults
> > in the demangler and recover from them gracefully.  A warning is
> > printed the first time a fault occurs.  Example sessions with and
> > without these patches are included below.
> > 
> > None of the wrapped code uses cleanups, so each caught failure
> > will leak a small amount of memory.  This is undesirable but I
> > think the benefits here outweigh this drawback.
> > 
> > Ok to commit?
> 
> No.  It's this skind of duct-tape that will make sure that bugs in
> the demangler won't get fixed.  Apart from removing the incentive to
> fix the bugs, these SIGSEGV signal handlers make actually fixing the
> bugs harder as you won't have core dumps.

I would normally agree with you 100% on this issue Mark, but in this
case I think a handler is justified.  If the demangler crashes because
of a symbol in the users program then the user cannot debug their
program at all.  If the demangler were simple and well understood then
that would be fine but it's not: the demangler is complex, the
specification it's following is complex, and everything's complicated
further because you can't allocate heap and you have to roll your own
data structures.  The reality is that the libiberty demangler is a
breeding ground for segfaults, and GDB needs to be able to deal with
this.

It's true that you don't get core dumps with this patch, but what you
do get in return is a printed warning that includes the symbol that
caused the crash.  That's all you need in most cases.  The five recent
demangler crashes (14963, 16593, 16752, 16817 and 16845) all required
digging by either the reporter or a GDB developer to uncover the
failing symbol.  Printing the offending symbol means this work is
already done.

If the lack of core dumps is a showstopper for you then I can
update the patch to allow disabling the handler with
"maint set handle-demangler-crashes 0" or some similar thing.

> Besides, any signal handler that does more than just setting a flag
> is probably broken.  Did you verify that you only call async-signal-
> safe functions in the signal handler code path?

I didn't think this was necessary as to my knowledge SIGSEGV is only
ever emitted synchronously.  If it is an issue then the patch could
be reworked to use (sig)longjmp as included below.

Thanks,
Gary


diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 91533e8..5e79fb4 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -36,6 +36,7 @@
 #include "value.h"
 #include "cp-abi.h"
 #include "language.h"
+#include <signal.h>
 
 #include "safe-ctype.h"
 
@@ -1505,12 +1506,89 @@ cp_lookup_rtti_type (const char *name, struct block *block)
   return rtti_type;
 }
 
+#ifdef SIGSEGV
+
+/* PortabiWrap set/long jmp so that it's more portable.  */
+
+#if defined(HAVE_SIGSETJMP)
+#define SIGJMP_BUF		sigjmp_buf
+#define SIGSETJMP(buf)		sigsetjmp((buf), 1)
+#define SIGLONGJMP(buf,val)	siglongjmp((buf), (val))
+#else
+#define SIGJMP_BUF		jmp_buf
+#define SIGSETJMP(buf)		setjmp(buf)
+#define SIGLONGJMP(buf,val)	longjmp((buf), (val))
+#endif
+
+/* Stack context and environment for demangler crash recovery.  */
+
+static SIGJMP_BUF gdb_demangle_jmp_buf;
+
+/* Signal handler for gdb_demangle.  */
+
+static void
+gdb_demangle_signal_handler (int signo)
+{
+  SIGLONGJMP (gdb_demangle_jmp_buf, signo);
+}
+
+#endif
+
 /* A wrapper for bfd_demangle.  */
 
 char *
 gdb_demangle (const char *name, int options)
 {
-  return bfd_demangle (NULL, name, options);
+  char *result = NULL;
+  int crash_signal = 0;
+
+#ifdef SIGSEGV
+#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
+
+  crash_signal = SIGSETJMP (gdb_demangle_jmp_buf);
+#endif
+
+  if (crash_signal == 0)
+    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 (crash_signal != 0)
+    {
+      static int warning_printed = 0;
+
+      if (!warning_printed)
+	{
+	  warning ("internal error: demangler failed with signal %d\n"
+		   "Unable to demangle '%s'\n"
+		   "This is a bug, "
+		   "please report it to the GDB maintainers.",
+		   crash_signal, name);
+
+	  warning_printed = 1;
+	}
+
+      result = NULL;
+    }
+
+  return result;
 }
 
 /* Don't allow just "maintenance cplus".  */

  reply	other threads:[~2014-05-09 15:33 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-09 10:07 Gary Benson
2014-05-09 10:09 ` [PATCH 1/2] " Gary Benson
2014-05-09 10:10 ` [PATCH 2/2] " Gary Benson
2014-05-09 11:20 ` [PATCH 0/2] " Mark Kettenis
2014-05-09 15:33   ` Gary Benson [this message]
2014-05-11  5:17     ` Doug Evans
2014-05-13 10:20       ` Gary Benson
2014-05-13 19:29         ` Tom Tromey
2014-05-14 13:07           ` Gary Benson
2014-05-13 19:39         ` Tom Tromey
2014-05-14  9:15           ` Gary Benson
2014-05-11 20:23     ` Mark Kettenis
2014-05-13 10:21       ` Gary Benson
2014-05-13 16:05         ` Pedro Alves
2014-05-15 13:24           ` Gary Benson
2014-05-15 14:07             ` Pedro Alves
2014-05-15 14:28               ` Gary Benson
2014-05-15 15:25                 ` Pedro Alves
2014-05-16 11:06             ` Pedro Alves
2014-05-10 20:55   ` Florian Weimer
2014-05-11  5:10     ` Doug Evans
2014-05-13 10:22     ` Gary Benson
2014-05-13 18:22       ` Florian Weimer
2014-05-13 18:42         ` Pedro Alves
2014-05-13 19:16           ` Gary Benson
2014-05-13 19:19             ` Pedro Alves
2014-05-14  9:11               ` Gary Benson
2014-05-13 19:20           ` Florian Weimer
2014-05-13 19:22             ` Pedro Alves
2014-05-13 19:22         ` Gary Benson
2014-05-13 19:36           ` Tom Tromey
2014-05-14  9:13             ` Gary Benson
2014-05-14 14:18     ` Pedro Alves
2014-05-14 16:08       ` Andrew Burgess
2014-05-14 18:32         ` Pedro Alves
2014-05-15 13:25           ` Gary Benson
2014-05-15 16:01             ` Pedro Alves
2014-05-15 13:27       ` Gary Benson
2014-05-20 17:05       ` Tom Tromey
2014-05-20 18:40         ` Stan Shebs
2014-05-20 19:36           ` Tom Tromey
2014-05-20 20:23             ` Joel Brobecker
2014-05-22 12:56               ` Gary Benson
2014-05-22 13:09                 ` Joel Brobecker
2014-05-22 14:13                 ` Pedro Alves
2014-05-22 15:57                   ` Gary Benson
2014-05-22 13:18           ` Gary Benson
2014-05-22 14:09         ` Gary Benson
2014-05-22 14:40           ` Mark Kettenis
2014-05-22 20:42             ` Gary Benson

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=20140509153305.GA13345@blade.nx \
    --to=gbenson@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=mark.kettenis@xs4all.nl \
    /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).