diff options
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/remote.c | 22 | ||||
-rw-r--r-- | gdb/target-delegates.c | 21 | ||||
-rw-r--r-- | gdb/target.c | 21 | ||||
-rw-r--r-- | gdb/target.h | 13 |
5 files changed, 88 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2a05df21525..ac6c2819df2 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,16 @@ 2016-04-12 Pedro Alves <palves@redhat.com> + * remote.c (remote_pass_ctrlc): New function. + (init_remote_ops): Install it. + * target.c (target_terminal_inferior): Pass pending Ctrl-C to the + target. + (target_pass_ctrlc, default_target_pass_ctrlc): New functions. + * target.h (struct target_ops) <to_pass_ctrlc>: New method. + (target_pass_ctrlc, default_target_pass_ctrlc): New declarations. + * target-delegates.c: Regenerate. + +2016-04-12 Pedro Alves <palves@redhat.com> + * infcmd.c (interrupt_target_1): Call target_stop is in non-stop mode. * linux-nat.c (linux_nat_interrupt): Delete. diff --git a/gdb/remote.c b/gdb/remote.c index 1bd2bcfe296..0b2d25fde37 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -5875,6 +5875,27 @@ remote_interrupt (struct target_ops *self, ptid_t ptid) remote_interrupt_as (); } +/* Implement the to_pass_ctrlc function for the remote targets. */ + +static void +remote_pass_ctrlc (struct target_ops *self) +{ + struct remote_state *rs = get_remote_state (); + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "remote_pass_ctrlc called\n"); + + /* If we're starting up, we're not fully synced yet. Quit + immediately. */ + if (rs->starting_up) + quit (); + /* If ^C has already been sent once, offer to disconnect. */ + else if (rs->ctrlc_pending_p) + interrupt_query (); + else + target_interrupt (inferior_ptid); +} + /* Ask the user what to do when an interrupt is received. */ static void @@ -13056,6 +13077,7 @@ Specify the serial device it is connected to\n\ remote_ops.to_get_ada_task_ptid = remote_get_ada_task_ptid; remote_ops.to_stop = remote_stop; remote_ops.to_interrupt = remote_interrupt; + remote_ops.to_pass_ctrlc = remote_pass_ctrlc; remote_ops.to_check_pending_interrupt = remote_check_pending_interrupt; remote_ops.to_xfer_partial = remote_xfer_partial; remote_ops.to_rcmd = remote_rcmd; diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c index d23bc759e5a..640803a3402 100644 --- a/gdb/target-delegates.c +++ b/gdb/target-delegates.c @@ -1608,6 +1608,23 @@ debug_interrupt (struct target_ops *self, ptid_t arg1) } static void +delegate_pass_ctrlc (struct target_ops *self) +{ + self = self->beneath; + self->to_pass_ctrlc (self); +} + +static void +debug_pass_ctrlc (struct target_ops *self) +{ + fprintf_unfiltered (gdb_stdlog, "-> %s->to_pass_ctrlc (...)\n", debug_target.to_shortname); + debug_target.to_pass_ctrlc (&debug_target); + fprintf_unfiltered (gdb_stdlog, "<- %s->to_pass_ctrlc (", debug_target.to_shortname); + target_debug_print_struct_target_ops_p (&debug_target); + fputs_unfiltered (")\n", gdb_stdlog); +} + +static void delegate_check_pending_interrupt (struct target_ops *self) { self = self->beneath; @@ -4194,6 +4211,8 @@ install_delegators (struct target_ops *ops) ops->to_stop = delegate_stop; if (ops->to_interrupt == NULL) ops->to_interrupt = delegate_interrupt; + if (ops->to_pass_ctrlc == NULL) + ops->to_pass_ctrlc = delegate_pass_ctrlc; if (ops->to_check_pending_interrupt == NULL) ops->to_check_pending_interrupt = delegate_check_pending_interrupt; if (ops->to_rcmd == NULL) @@ -4442,6 +4461,7 @@ install_dummy_methods (struct target_ops *ops) ops->to_thread_name = tdefault_thread_name; ops->to_stop = tdefault_stop; ops->to_interrupt = tdefault_interrupt; + ops->to_pass_ctrlc = default_target_pass_ctrlc; ops->to_check_pending_interrupt = tdefault_check_pending_interrupt; ops->to_rcmd = default_rcmd; ops->to_pid_to_exec_file = tdefault_pid_to_exec_file; @@ -4598,6 +4618,7 @@ init_debug_target (struct target_ops *ops) ops->to_thread_name = debug_thread_name; ops->to_stop = debug_stop; ops->to_interrupt = debug_interrupt; + ops->to_pass_ctrlc = debug_pass_ctrlc; ops->to_check_pending_interrupt = debug_check_pending_interrupt; ops->to_rcmd = debug_rcmd; ops->to_pid_to_exec_file = debug_pid_to_exec_file; diff --git a/gdb/target.c b/gdb/target.c index ac66a3a8993..d580983c4fa 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -491,6 +491,11 @@ target_terminal_inferior (void) inferior's terminal modes. */ (*current_target.to_terminal_inferior) (¤t_target); terminal_state = terminal_is_inferior; + + /* If the user hit C-c before, pretend that it was hit right + here. */ + if (check_quit_flag ()) + target_pass_ctrlc (); } /* See target.h. */ @@ -3360,6 +3365,22 @@ target_interrupt (ptid_t ptid) /* See target.h. */ void +target_pass_ctrlc (void) +{ + (*current_target.to_pass_ctrlc) (¤t_target); +} + +/* See target.h. */ + +void +default_target_pass_ctrlc (struct target_ops *ops) +{ + target_interrupt (inferior_ptid); +} + +/* See target.h. */ + +void target_check_pending_interrupt (void) { (*current_target.to_check_pending_interrupt) (¤t_target); diff --git a/gdb/target.h b/gdb/target.h index 26c857938e5..00625fec63c 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -645,6 +645,8 @@ struct target_ops TARGET_DEFAULT_IGNORE (); void (*to_interrupt) (struct target_ops *, ptid_t) TARGET_DEFAULT_IGNORE (); + void (*to_pass_ctrlc) (struct target_ops *) + TARGET_DEFAULT_FUNC (default_target_pass_ctrlc); void (*to_check_pending_interrupt) (struct target_ops *) TARGET_DEFAULT_IGNORE (); void (*to_rcmd) (struct target_ops *, @@ -1716,6 +1718,17 @@ extern void target_stop (ptid_t ptid); extern void target_interrupt (ptid_t ptid); +/* Pass a ^C, as determined to have been pressed by checking the quit + flag, to the target. Normally calls target_interrupt, but remote + targets may take the opportunity to detect the remote side is not + responding and offer to disconnect. */ + +extern void target_pass_ctrlc (void); + +/* The default target_ops::to_pass_ctrlc implementation. Simply calls + target_interrupt. */ +extern void default_target_pass_ctrlc (struct target_ops *ops); + /* Some targets install their own SIGINT handler while the target is running. This method is called from the QUIT macro to give such targets a chance to process a Ctrl-C. The target may e.g., choose |