X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fevent-top.c;h=ac0f3701016e19450f516ad510b20cc26d57b758;hb=c3699833af0343d13d7d39b3c589d3ac5b930137;hp=bb8ba5cfe5779747f59d95db40280c4faba3a4b1;hpb=c6fdd8b2052baa9b7a27d4d34f109c9622b53509;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/event-top.c b/gdb/event-top.c index bb8ba5cfe5..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. @@ -24,8 +24,8 @@ #include "inferior.h" #include "infrun.h" #include "target.h" -#include "terminal.h" /* for job_control */ -#include "event-loop.h" +#include "terminal.h" +#include "gdbsupport/event-loop.h" #include "event-top.h" #include "interps.h" #include @@ -37,9 +37,11 @@ #include "gdbcmd.h" /* for dont_repeat() */ #include "annotate.h" #include "maint.h" -#include "common/buffer.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" @@ -86,11 +88,11 @@ static void async_sigterm_handler (gdb_client_data arg); ezannoni: as of 1999-04-29 I expect that this variable will not be used after gdb is changed to use the event loop as default engine, and event-top.c is merged into top.c. */ -int set_editing_cmd_var; +bool set_editing_cmd_var; /* This is used to display the notification of the completion of an asynchronous execution command. */ -int exec_done_display_p = 0; +bool exec_done_display_p = false; /* Used by the stdin event handler to compensate for missed stdin events. Setting this to a non-zero value inside an stdin callback makes the callback @@ -193,7 +195,7 @@ gdb_rl_callback_read_char_wrapper (gdb_client_data client_data) /* Rethrow using the normal EH mechanism. */ if (gdb_expt.reason < 0) - throw_exception (gdb_expt); + throw_exception (std::move (gdb_expt)); } /* GDB's readline callback handler. Calls the current INPUT_HANDLER, @@ -205,11 +207,15 @@ gdb_rl_callback_read_char_wrapper (gdb_client_data client_data) static void gdb_rl_callback_handler (char *rl) noexcept { - struct gdb_exception gdb_rl_expt; + /* This is static to avoid undefined behavior when calling longjmp + -- gdb_exception has a destructor with side effects. */ + static struct gdb_exception gdb_rl_expt; struct ui *ui = current_ui; try { + /* Ensure the exception is reset on each call. */ + gdb_rl_expt = {}; ui->input_handler (gdb::unique_xmalloc_ptr (rl)); } catch (gdb_exception &ex) @@ -411,13 +417,13 @@ 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); } } /* Return the top level prompt, as specified by "set prompt", possibly - overriden by the python gdb.prompt_hook hook, and then composed + overridden by the python gdb.prompt_hook hook, and then composed with the prompt prefix and suffix (annotations). */ static std::string @@ -630,11 +636,10 @@ command_line_append_input_line (struct buffer *cmd_line_buffer, const char *rl) If REPEAT, handle command repetitions: - If the input command line is NOT empty, the command returned is - copied into the global 'saved_command_line' var so that it can - be repeated later. + saved using save_command_line () so that it can be repeated later. - - OTOH, if the input command line IS empty, return the previously - saved command instead of the empty input line. + - OTOH, if the input command line IS empty, return the saved + command instead of the empty input line. */ char * @@ -669,7 +674,7 @@ handle_line_of_input (struct buffer *cmd_line_buffer, server_command = startswith (cmd, SERVER_COMMAND_PREFIX); if (server_command) { - /* Note that we don't set `saved_command_line'. Between this + /* Note that we don't call `save_command_line'. Between this and the check in dont_repeat, this insures that repeating will still do the right thing. */ return cmd + strlen (SERVER_COMMAND_PREFIX); @@ -709,7 +714,7 @@ handle_line_of_input (struct buffer *cmd_line_buffer, for (p1 = cmd; *p1 == ' ' || *p1 == '\t'; p1++) ; if (repeat && *p1 == '\0') - return saved_command_line; + return get_saved_command_line (); /* Add command to history if appropriate. Note: lines consisting solely of comments are also added to the command history. This @@ -724,9 +729,8 @@ handle_line_of_input (struct buffer *cmd_line_buffer, /* Save into global buffer if appropriate. */ if (repeat) { - xfree (saved_command_line); - saved_command_line = xstrdup (cmd); - return saved_command_line; + save_command_line (cmd); + return get_saved_command_line (); } else return cmd; @@ -845,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 @@ -912,6 +955,8 @@ async_init_signals (void) sigtstp_token = create_async_signal_handler (async_sigtstp_handler, NULL); #endif + + install_handle_sigsegv (); } /* See defs.h. */ @@ -1093,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: ??????????? */ @@ -1125,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); @@ -1150,7 +1199,7 @@ handle_sigfpe (int sig) signal (sig, handle_sigfpe); } -/* Event loop will call this functin to process a SIGFPE. */ +/* Event loop will call this function to process a SIGFPE. */ static void async_float_handler (gdb_client_data arg) {