target remote: Don't rely on immediate_quit (introduce quit handlers)

remote.c is the last user of immediate_quit.  It's relied on to
immediately break the initial remote connection sync up, if the user
does Ctrl-C, assuming that was because the target isn't responding.
At that stage, since the connection isn't synced yet, disconnecting is
the only safe thing to do.  This commit reworks that, to not rely on
throwing from the SIGINT signal handler.

So, this commit:

- Introduces the concept of a "quit handler".  This is used to
  override what does the QUIT macro do when the quit flag is set.

- Makes the "struct serial" reachar / write code call QUIT in the
  partial read/write loops, so the current quit handler is invoked
  whenever a serial->read_prim / serial->write_prim returns EINTR.

- Makes the "struct serial" reachar / write code call
  interruptible_select instead of gdb_select, so that QUITs are
  detected in a race-free manner.

- Stops remote.c from setting immediate_quit during the initial
  connection.

- Instead, we install a custom quit handler whenever we're calling
  into the serial code.  This custom quit handler knows to immediately
  throw a quit when we're in the initial connection setup, and
  otherwise defer handling the quit/Ctrl-C request to later, when
  we're safely out of a packet command/response sequence.  This also
  is what is now responsible for handling "double Ctrl-C because
  target connection is stuck/wedged."

- remote.c no longer installs a specialized SIGINT handlers, and
  instead re-uses the quit flag.  Since we want to rely on the QUIT
  macro, the SIGINT handler must also set the quit.  And the easiest
  is just to not install custom SIGINT handler in remote.c.  Let the
  standard SIGINT handler do its job of setting the quit flag.
  Centralizing SIGINT handlers seems like a good thing to me, anyway.

gdb/ChangeLog:
2016-04-12  Pedro Alves  <palves@redhat.com>

	* defs.h (quit_handler_ftype, quit_handler)
	(make_cleanup_override_quit_handler, default_quit_handler): New.
	(QUIT): Adjust comments.
	* event-top.c (default_quit_handler): New function.
	(quit_handler): New global.
	(struct quit_handler_cleanup_data): New.
	(restore_quit_handler, restore_quit_handler_dtor)
	(make_cleanup_override_quit_handler): New.
	(async_request_quit): Call QUIT.
	* remote.c (struct remote_state) <got_ctrlc_during_io>: New field.
	(async_sigint_remote_twice_token, async_sigint_remote_token):
	Delete.
	(remote_close): Update comments.
	(remote_start_remote): Don't set immediate_quit.  Set starting_up
	earlier.
	(remote_serial_quit_handler, remote_unpush_and_throw): New
	functions.
	(remote_open_1): Clear got_ctrlc_during_io.  Set
	remote_async_terminal_ours_p unconditionally.
	(async_initialize_sigint_signal_handler)
	(async_handle_remote_sigint, async_handle_remote_sigint_twice)
	(remote_check_pending_interrupt, async_remote_interrupt)
	(async_remote_interrupt_twice)
	(async_cleanup_sigint_signal_handler, ofunc)
	(sync_remote_interrupt, sync_remote_interrupt_twice): Delete.
	(remote_terminal_inferior, remote_terminal_ours): Remove async
	checks.
	(remote_wait_as): Don't install a SIGINT handler in sync mode.
	(readchar, remote_serial_write): Override the quit handler with
	remote_serial_quit_handler.
	(getpkt_or_notif_sane_1): Don't call QUIT.
	(initialize_remote_ops): Don't install
	remote_check_pending_interrupt.
	(_initialize_remote): Don't create async_sigint_remote_token and
	async_sigint_remote_twice_token.
	* ser-base.c (ser_base_wait_for): Call QUIT and use
	interruptible_select.
	(ser_base_write): Call QUIT.
	* ser-go32.c (dos_readchar, dos_write): Call QUIT.
	* ser-unix.c (wait_for): Don't use VTIME.  Always take the
	gdb_select path, but call QUIT and interruptible_select.
	* utils.c (maybe_quit): Call the current quit handler.  Don't call
	target_check_pending_interrupt.
	(defaulted_query, prompt_for_continue): Override the quit handler
	with the default quit handler.
This commit is contained in:
Pedro Alves
2016-04-12 16:49:32 +01:00
parent a12ac51333
commit 048094accc
8 changed files with 285 additions and 254 deletions

View File

@ -1086,11 +1086,13 @@ quit (void)
void
maybe_quit (void)
{
if (check_quit_flag () || sync_quit_force_run)
if (sync_quit_force_run)
quit ();
quit_handler ();
if (deprecated_interactive_hook)
deprecated_interactive_hook ();
target_check_pending_interrupt ();
}
@ -1318,6 +1320,7 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
/* We'll need to handle input. */
target_terminal_ours ();
make_cleanup_override_quit_handler (default_quit_handler);
while (1)
{
@ -1892,6 +1895,7 @@ prompt_for_continue (void)
/* We'll need to handle input. */
make_cleanup_restore_target_terminal ();
target_terminal_ours ();
make_cleanup_override_quit_handler (default_quit_handler);
/* Call gdb_readline_wrapper, not readline, in order to keep an
event loop running. */