diff options
Diffstat (limited to 'gdb/cp-support.c')
-rw-r--r-- | gdb/cp-support.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/gdb/cp-support.c b/gdb/cp-support.c index cd732b6..253369b 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -1539,7 +1539,16 @@ gdb_demangle (const char *name, int options) 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 @@ -1559,6 +1568,14 @@ gdb_demangle (const char *name, int options) { 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 |