diff options
Diffstat (limited to 'gdb/event-top.c')
-rw-r--r-- | gdb/event-top.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/gdb/event-top.c b/gdb/event-top.c index 6c6e0ff..9ec599e 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -848,6 +848,45 @@ gdb_readline_no_editing_callback (gdb_client_data client_data) } +/* See event-top.h. */ + +thread_local void (*thread_local_segv_handler) (int); + +static void handle_sigsegv (int sig); + +/* Install the SIGSEGV handler. */ +static void +install_handle_sigsegv () +{ +#if defined (HAVE_SIGACTION) + struct sigaction sa; + sa.sa_handler = handle_sigsegv; + sigemptyset (&sa.sa_mask); +#ifdef HAVE_SIGALTSTACK + sa.sa_flags = SA_ONSTACK; +#else + sa.sa_flags = 0; +#endif + sigaction (SIGSEGV, &sa, nullptr); +#else + signal (SIGSEGV, handle_sigsegv); +#endif +} + +/* Handler for SIGSEGV. */ + +static void +handle_sigsegv (int sig) +{ + install_handle_sigsegv (); + + if (thread_local_segv_handler == nullptr) + abort (); + thread_local_segv_handler (sig); +} + + + /* The serial event associated with the QUIT flag. set_quit_flag sets this, and check_quit_flag clears it. Used by interruptible_select to be able to do interruptible I/O with no race with the SIGINT @@ -915,6 +954,8 @@ async_init_signals (void) sigtstp_token = create_async_signal_handler (async_sigtstp_handler, NULL); #endif + + install_handle_sigsegv (); } /* See defs.h. */ |