Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <palves@redhat.com>
To: Yao Qi <qiyaoltc@gmail.com>, gdb-patches@sourceware.org
Subject: Re: [RFC master/7.12.1] Don't propagate C++ exceptions across readline using SjLj on SjLj-based exception unwinding
Date: Tue, 20 Dec 2016 11:50:00 -0000	[thread overview]
Message-ID: <fdfc0c0a-97c2-4f79-0914-b07adb6afe16@redhat.com> (raw)
In-Reply-To: <1482158537-17839-1-git-send-email-yao.qi@linaro.org>

On 12/19/2016 02:42 PM, Yao Qi wrote:
> Nowadays, we propagate C++ exceptions across readline using
> setjmp/longjmp 89525768cd086a0798a504c81fdf7ebcd4c904e1
> (Propagate GDB/C++ exceptions across readline using sj/lj-based TRY/CATCH)
> because DWARF-based unwinding can't cross C function (see
> details from the commit above).  However, SjLj-based exception
> unwinding doesn't have such issue.

Nice find.

I built a sjlj-based GCC trunk here, and building GDB with that
indeed triggers this.

> 
> What is more, looks longjmp may break the SjLj-based exception
> handling, because _Unwind_SjLj_Unregister, which is put the exit
> of function, is not executed due to longjmp.
> 
>  (gdb) [New Thread 2936.0xb80]
>  kill
> 
>  Thread 1 received signal SIGSEGV, Segmentation fault.
>  0x03ff662b in ?? ()
>  top?bt 15
>  #0  0x03ff662b in ?? ()
>  #1  0x00526b92 in stdin_event_handler (error=0, client_data=0x172ed8)
>     at ../../binutils-gdb/gdb/event-top.c:555
>  #2  0x00525a94 in handle_file_event (ready_mask=<optimized out>,
>     file_ptr=0x3ff5cb8) at ../../binutils-gdb/gdb/event-loop.c:733
...

> 
> I dig into libcc/unwind-sjlj.c and gcc/except.c, but I still
> don't find much clue.  This patch fixes this issue by not propagating
> the exception via setjmp/longjmp if __USING_SJLJ_EXCEPTIONS__.

I think I have a working approach that isn't specific to sjlj
exceptions, which I'd prefer.  I.e., use "noexcept", to make
the compiler understand that the function doesn't throw, and hence
doesn't need to issue _Unwind_SjLj_Register / _Unwind_SjLj_Unregister
calls.  That seems to do the trick.  I tried both -O0 and -O2 (with
GCC trunk).  Does this work for you too?

From fd8544c25b0f383fcc9517687a38c538d91e53c1 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Tue, 20 Dec 2016 11:26:36 +0000
Subject: [PATCH] noexcept

---
 gdb/event-top.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/gdb/event-top.c b/gdb/event-top.c
index acf8474..fa58def 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -157,10 +157,12 @@ void (*after_char_processing_hook) (void);
    sjlj-based TRY/CATCH mechanism, which knows to handle multiple
    levels of active setjmp/longjmp frames, needed in order to handle
    the readline callback recursing, as happens with e.g., secondary
-   prompts / queries, through gdb_readline_wrapper.  */
+   prompts / queries, through gdb_readline_wrapper.  This must be
+   noexcept in order to avoid problems with mixing sjlj and
+   (sjlj-based) C++ exceptions.  */
 
-static void
-gdb_rl_callback_read_char_wrapper (gdb_client_data client_data)
+static struct gdb_exception
+gdb_rl_callback_read_char_wrapper_noexcept () noexcept
 {
   struct gdb_exception gdb_expt = exception_none;
 
@@ -180,6 +182,15 @@ gdb_rl_callback_read_char_wrapper (gdb_client_data client_data)
     }
   END_CATCH_SJLJ
 
+  return gdb_expt;
+}
+
+static void
+gdb_rl_callback_read_char_wrapper (gdb_client_data client_data)
+{
+  struct gdb_exception gdb_expt
+    = gdb_rl_callback_read_char_wrapper_noexcept ();
+
   /* Rethrow using the normal EH mechanism.  */
   if (gdb_expt.reason < 0)
     throw_exception (gdb_expt);
@@ -187,10 +198,12 @@ gdb_rl_callback_read_char_wrapper (gdb_client_data client_data)
 
 /* GDB's readline callback handler.  Calls the current INPUT_HANDLER,
    and propagates GDB exceptions/errors thrown from INPUT_HANDLER back
-   across readline.  See gdb_rl_callback_read_char_wrapper.  */
+   across readline.  See gdb_rl_callback_read_char_wrapper.  This must
+   be noexcept in order to avoid problems with mixing sjlj and
+   (sjlj-based) C++ exceptions.  */
 
 static void
-gdb_rl_callback_handler (char *rl)
+gdb_rl_callback_handler (char *rl) noexcept
 {
   struct gdb_exception gdb_rl_expt = exception_none;
   struct ui *ui = current_ui;
-- 
2.5.5



  reply	other threads:[~2016-12-20 11:50 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-19 14:42 Yao Qi
2016-12-20 11:50 ` Pedro Alves [this message]
2016-12-20 14:33   ` Yao Qi
2016-12-20 16:25     ` Pedro Alves
2016-12-20 19:43       ` Pedro Alves

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=fdfc0c0a-97c2-4f79-0914-b07adb6afe16@redhat.com \
    --to=palves@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=qiyaoltc@gmail.com \
    /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