From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 33829 invoked by alias); 18 Mar 2016 19:24:38 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 33232 invoked by uid 89); 18 Mar 2016 19:24:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=offer, synced X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 18 Mar 2016 19:24:35 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 02C4B80E47 for ; Fri, 18 Mar 2016 19:18:50 +0000 (UTC) Received: from cascais.lan (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u2IJIYkF028091 for ; Fri, 18 Mar 2016 15:18:49 -0400 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 17/30] Pass Ctrl-C to the target in target_terminal_inferior Date: Fri, 18 Mar 2016 19:24:00 -0000 Message-Id: <1458328714-4938-18-git-send-email-palves@redhat.com> In-Reply-To: <1458328714-4938-1-git-send-email-palves@redhat.com> References: <1458328714-4938-1-git-send-email-palves@redhat.com> X-SW-Source: 2016-03/txt/msg00361.txt.bz2 If the user presses Ctrl-C immediately before target_terminal_inferior is called and the target is resumed, instead of after, the Ctrl-C ends up pending in the quit flag until the target next stops. remote.c has this bit to handle this: if (!target_is_async_p ()) { ofunc = signal (SIGINT, sync_remote_interrupt); /* If the user hit C-c before this packet, or between packets, pretend that it was hit right here. */ if (check_quit_flag ()) sync_remote_interrupt (SIGINT); } But that's only reachable if async is off, while async is on by default nowadays. It's also obviously not reacheable on native targets. This patch generalizes that to all targets. We can't remove that remote.c bit yet, until we get rid of the sync SIGINT handler though. That'll be done later in the series. gdb/ChangeLog: yyyy-mm-dd Pedro Alves * 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) : New method. (target_pass_ctrlc, default_target_pass_ctrlc): New declarations. * target-delegates.c: Regenerate. --- gdb/remote.c | 22 ++++++++++++++++++++++ gdb/target-delegates.c | 21 +++++++++++++++++++++ gdb/target.c | 21 +++++++++++++++++++++ gdb/target.h | 13 +++++++++++++ 4 files changed, 77 insertions(+) diff --git a/gdb/remote.c b/gdb/remote.c index f932455..3c8de40 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -5873,6 +5873,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 @@ -13054,6 +13075,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 d23bc75..640803a 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 ac66a3a..d580983 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 26c8579..00625fec 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 -- 2.5.0