Introduce thread-safe way to handle SIGSEGV

The gdb demangler installs a SIGSEGV handler in order to protect gdb
from demangler bugs.  However, this is not thread-safe, as signal
handlers are global to the process.

This patch changes gdb to always install a global SIGSEGV handler, and
then lets threads indicate their interest in handling the signal by
setting a thread-local variable.

This patch then arranges for the demangler code to use this; being
sure to arrange for calls to warning and the like to be done on the
main thread.

One thing I wondered while writing this patch is if there are any
systems that do not have "sigaction".  If gdb could assume this, it
would simplify this code.

gdb/ChangeLog
2019-11-26  Tom Tromey  <tom@tromey.com>

	* event-top.h (thread_local_segv_handler): Declare.
	* event-top.c (thread_local_segv_handler): New global.
	(install_handle_sigsegv, handle_sigsegv): New functions.
	(async_init_signals): Install SIGSEGV handler.
	* cp-support.c (gdb_demangle_jmp_buf): Change type.  Now
	thread-local.
	(report_failed_demangle): New function.
	(gdb_demangle): Make core_dump_allowed atomic.  Remove signal
	handler-setting code, instead use segv_handler.  Run warning code
	on main thread.

Change-Id: Ic832bbb033b64744e4b44f14b41db7e4168ce427
This commit is contained in:
Tom Tromey 2019-03-04 15:12:04 -07:00
parent 9411c49ecc
commit 3b3978bca2
4 changed files with 129 additions and 71 deletions

View file

@ -70,4 +70,10 @@ extern void gdb_rl_callback_handler_install (const char *prompt);
currently installed. */
extern void gdb_rl_callback_handler_reinstall (void);
/* The SIGSEGV handler for this thread, or NULL if there is none. GDB
always installs a global SIGSEGV handler, and then lets threads
indicate their interest in handling the signal by setting this
thread-local variable. */
extern thread_local void (*thread_local_segv_handler) (int);
#endif