X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fevent-top.c;h=5feb2928e22eb3e72bb8248a5abae337a28c48b0;hb=cedfc77485dbb566619dc1e2d729ce0a70d1a4ad;hp=920b47f7e3cb4774612082e0c790c70d8eacd0aa;hpb=b6fb1ee51c9a773d2d6044993af6c0fd7499638f;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/event-top.c b/gdb/event-top.c index 920b47f7e3..5feb2928e2 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -24,7 +24,7 @@ #include "inferior.h" #include "infrun.h" #include "target.h" -#include "terminal.h" /* for job_control */ +#include "terminal.h" #include "event-loop.h" #include "event-top.h" #include "interps.h" @@ -37,9 +37,10 @@ #include "gdbcmd.h" /* for dont_repeat() */ #include "annotate.h" #include "maint.h" -#include "buffer.h" +#include "gdbsupport/buffer.h" #include "ser-event.h" #include "gdb_select.h" +#include "gdbsupport/gdb-sigmask.h" /* readline include files. */ #include "readline/readline.h" @@ -86,11 +87,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 @@ -164,7 +165,7 @@ void (*after_char_processing_hook) (void); static struct gdb_exception gdb_rl_callback_read_char_wrapper_noexcept () noexcept { - struct gdb_exception gdb_expt = exception_none; + struct gdb_exception gdb_expt; /* C++ exceptions can't normally be thrown across readline (unless it is built with -fexceptions, but it won't by default on many @@ -178,7 +179,7 @@ gdb_rl_callback_read_char_wrapper_noexcept () noexcept } CATCH_SJLJ (ex, RETURN_MASK_ALL) { - gdb_expt = ex; + gdb_expt = std::move (ex); } END_CATCH_SJLJ @@ -193,7 +194,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,18 +206,21 @@ 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 = exception_none; + /* 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 + try { + /* Ensure the exception is reset on each call. */ + gdb_rl_expt = {}; ui->input_handler (gdb::unique_xmalloc_ptr (rl)); } - CATCH (ex, RETURN_MASK_ALL) + catch (gdb_exception &ex) { - gdb_rl_expt = ex; + gdb_rl_expt = std::move (ex); } - END_CATCH /* If we caught a GDB exception, longjmp out of the readline callback. There's no other way for the callback to signal to @@ -418,7 +422,7 @@ display_gdb_prompt (const char *new_prompt) } /* 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 @@ -631,11 +635,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 * @@ -670,7 +673,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); @@ -710,7 +713,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 @@ -725,9 +728,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; @@ -846,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 (); /* 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 @@ -913,6 +954,8 @@ async_init_signals (void) sigtstp_token = create_async_signal_handler (async_sigtstp_handler, NULL); #endif + + install_handle_sigsegv (); } /* See defs.h. */ @@ -1082,27 +1125,25 @@ static void async_disconnect (gdb_client_data arg) { - TRY + try { quit_cover (); } - CATCH (exception, RETURN_MASK_ALL) + catch (const gdb_exception &exception) { fputs_filtered ("Could not kill the program being debugged", gdb_stderr); exception_print (gdb_stderr, exception); } - END_CATCH - TRY + try { pop_all_targets (); } - CATCH (exception, RETURN_MASK_ALL) + catch (const gdb_exception &exception) { } - END_CATCH signal (SIGHUP, SIG_DFL); /*FIXME: ??????????? */ raise (SIGHUP); @@ -1128,7 +1169,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); @@ -1153,7 +1194,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) {