X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fevent-top.c;h=ac0f3701016e19450f516ad510b20cc26d57b758;hb=60db1b8565060f4bd2287b060ea9724c93289982;hp=0396dbcc52de74db3fbe32d41e33f04a3451c968;hpb=405feb71d4733a36cdc0629e9e4ccecd1a40dc39;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/event-top.c b/gdb/event-top.c index 0396dbcc52..ac0f370101 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -1,6 +1,6 @@ /* Top level stuff for GDB, the GNU debugger. - Copyright (C) 1999-2019 Free Software Foundation, Inc. + Copyright (C) 1999-2020 Free Software Foundation, Inc. Written by Elena Zannoni of Cygnus Solutions. @@ -25,7 +25,7 @@ #include "infrun.h" #include "target.h" #include "terminal.h" -#include "event-loop.h" +#include "gdbsupport/event-loop.h" #include "event-top.h" #include "interps.h" #include @@ -39,7 +39,9 @@ #include "maint.h" #include "gdbsupport/buffer.h" #include "ser-event.h" -#include "gdb_select.h" +#include "gdbsupport/gdb_select.h" +#include "gdbsupport/gdb-sigmask.h" +#include "async-event.h" /* readline include files. */ #include "readline/readline.h" @@ -415,7 +417,7 @@ display_gdb_prompt (const char *new_prompt) /* Don't use a _filtered function here. It causes the assumed character position to be off, since the newline we read from the user is not accounted for. */ - fputs_unfiltered (actual_gdb_prompt.c_str (), gdb_stdout); + fprintf_unfiltered (gdb_stdout, "%s", actual_gdb_prompt.c_str ()); gdb_flush (gdb_stdout); } } @@ -847,6 +849,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 (); /* ARI: 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 @@ -914,6 +955,8 @@ async_init_signals (void) sigtstp_token = create_async_signal_handler (async_sigtstp_handler, NULL); #endif + + install_handle_sigsegv (); } /* See defs.h. */ @@ -1095,12 +1138,16 @@ async_disconnect (gdb_client_data arg) exception_print (gdb_stderr, exception); } - try - { - pop_all_targets (); - } - catch (const gdb_exception &exception) + for (inferior *inf : all_inferiors ()) { + switch_to_inferior_no_thread (inf); + try + { + pop_all_targets (); + } + catch (const gdb_exception &exception) + { + } } signal (SIGHUP, SIG_DFL); /*FIXME: ??????????? */ @@ -1127,7 +1174,7 @@ async_sigtstp_handler (gdb_client_data arg) sigset_t zero; sigemptyset (&zero); - sigprocmask (SIG_SETMASK, &zero, 0); + gdb_sigmask (SIG_SETMASK, &zero, 0); } #elif HAVE_SIGSETMASK sigsetmask (0);