+2019-10-16 Christian Biesinger <cbiesinger@google.com>
+
+ * gdbsupport/gdb_setjmp.h (SIGSETJMP): Allow passing in the value to
+ pass on to sigsetjmp's second argument.
+ * cp-support.c (gdb_demangle): Unblock SIGSEGV if we caught a crash.
+
2019-10-16 Keith Seitz <keiths@redhat.com>
PR gdb/23567
ofunc = signal (SIGSEGV, gdb_demangle_signal_handler);
#endif
- crash_signal = SIGSETJMP (gdb_demangle_jmp_buf);
+ /* The signal handler may keep the signal blocked when we longjmp out
+ of it. If we have sigprocmask, we can use it to unblock the signal
+ afterwards and we can avoid the performance overhead of saving the
+ signal mask just in case the signal gets triggered. Otherwise, just
+ tell sigsetjmp to save the mask. */
+#ifdef HAVE_SIGPROCMASK
+ crash_signal = SIGSETJMP (gdb_demangle_jmp_buf, 0);
+#else
+ crash_signal = SIGSETJMP (gdb_demangle_jmp_buf, 1);
+#endif
}
#endif
{
static int error_reported = 0;
+#ifdef HAVE_SIGPROCMASK
+ /* If we got the signal, SIGSEGV may still be blocked; restore it. */
+ sigset_t segv_sig_set;
+ sigemptyset (&segv_sig_set);
+ sigaddset (&segv_sig_set, SIGSEGV);
+ sigprocmask (SIG_UNBLOCK, &segv_sig_set, NULL);
+#endif
+
if (!error_reported)
{
std::string short_msg
#ifdef HAVE_SIGSETJMP
#define SIGJMP_BUF sigjmp_buf
-#define SIGSETJMP(buf) sigsetjmp((buf), 1)
+#define SIGSETJMP(buf,val) sigsetjmp((buf), val)
#define SIGLONGJMP(buf,val) siglongjmp((buf), (val))
#else
#define SIGJMP_BUF jmp_buf
-#define SIGSETJMP(buf) setjmp(buf)
+/* We ignore val here because that's safer and avoids having to check
+ whether _setjmp exists. */
+#define SIGSETJMP(buf,val) setjmp(buf)
#define SIGLONGJMP(buf,val) longjmp((buf), (val))
#endif