From patchwork Tue Apr 7 12:49:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 6059 Received: (qmail 26600 invoked by alias); 7 Apr 2015 12:55:41 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 26591 invoked by uid 89); 7 Apr 2015 12:55:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 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; Tue, 07 Apr 2015 12:55:37 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t37CoA7h023939 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 7 Apr 2015 08:50:10 -0400 Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t37Cnox3022139 for ; Tue, 7 Apr 2015 08:50:09 -0400 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH v2 17/23] Fix interrupt-noterm.exp on targets always in non-stop Date: Tue, 7 Apr 2015 13:49:44 +0100 Message-Id: <1428410990-28560-18-git-send-email-palves@redhat.com> In-Reply-To: <1428410990-28560-1-git-send-email-palves@redhat.com> References: <1428410990-28560-1-git-send-email-palves@redhat.com> With "maint set target-non-stop on" we get: @@ -66,13 +66,16 @@ Continuing. interrupt (gdb) PASS: gdb.base/interrupt-noterm.exp: interrupt -Program received signal SIGINT, Interrupt. -PASS: gdb.base/interrupt-noterm.exp: inferior received SIGINT -testcase src/gdb/testsuite/gdb.base/interrupt-noterm.exp completed in 0 seconds +[process 12119] #1 stopped. +0x0000003615ebc6d0 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81 +81 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS) +FAIL: gdb.base/interrupt-noterm.exp: inferior received SIGINT (timeout) +testcase src/gdb/testsuite/gdb.base/interrupt-noterm.exp completed in 10 seconds That is, we get "[$thread] #1 stopped" instead of SIGINT. The issue is that we don't currently distinguish send "interrupt/ctrl-c" to target terminal vs "stop/pause" thread well; both cases go through "target_stop". And then, the native Linux backend (linux-nat.c) implements target_stop with SIGSTOP in non-stop mode, and SIGINT in all-stop mode. Since "maint set target-non-stop on" forces the backend to be always running in non-stop mode, even though the user-visible behavior is "set non-stop" is "off", "interrupt" causes a SIGSTOP instead of the SIGINT the test expects. Fix this by introducing a target_interrupt method to use in the "interrupt/ctrl-c" case, so "set non-stop off" can always work the same irrespective of "maint set target-non-stop on/off". I'm explictly considering changing the "set non-stop on" behavior as out of scope here. Most of the patch is an across-the-board rename of to_stop hook implementations to to_interrupt. The only targets where something more than a rename is being done are linux-nat.c and remote.c, which are the only targets that support async, and thus are the only ones the core side calls target_stop on. gdb/ChangeLog: 2015-04-07 Pedro Alves * darwin-nat.c (darwin_stop): Rename to ... (darwin_interrupt): ... this. (_initialize_darwin_inferior): Adjust. * gnu-nat.c (gnu_stop): Delete. (gnu_thread_alive): Don't install gnu_stop. * inf-ptrace.c (inf_ptrace_stop): Rename to ... (inf_ptrace_interrupt): ... this. (inf_ptrace_target): Adjust. * infcmd.c (interrupt_target_1): Use target_interrupt instead of target_stop. * linux-nat (linux_nat_stop): Rename to ... (linux_nat_interrupt): ... this. (linux_nat_stop): Reimplement. (linux_nat_add_target): Install linux_nat_interrupt. * monitor.c (monitor_stop): Rename to ... (monitor_interrupt): ... this. (init_base_monitor_ops): Adjust. * nto-procfs.c (nto_interrupt_twice): Rename to ... (nto_handle_sigint_twice): ... this. (nto_interrupt): Rename to ... (nto_handle_sigint): ... this. Call target_interrupt instead of target_stop. (procfs_wait, init_procfs_targets): Adjust. * procfs.c (procfs_target): Adjust. (procfs_stop): Rename to ... (procfs_interrupt): ... this. * remote-m32r-sdi.c (m32r_stop): Rename to ... (m32r_interrupt): ... this. (init_m32r_ops): Adjust. * remote-sim.c (gdbsim_stop_inferior): Rename to ... (gdbsim_interrupt_inferior): ... this. (gdbsim_stop): Rename to ... (gdbsim_interrupt): ... this. (gdbsim_cntrl_c): Adjust. (init_gdbsim_ops): Adjust. * remote.c (sync_remote_interrupt): Adjust comments. (remote_stop_as): Rename to ... (remote_interrupt_as): ... this. (remote_stop): Adjust comment. (remote_interrupt): New function. (init_remote_ops): Install remote_interrupt. * target.c (target_interrupt): New function. * target.h (struct target_ops) : New field. (target_interrupt): New declaration. * windows-nat.c (windows_stop): Rename to ... (windows_interrupt): ... this. * target-delegates.c: Regenerate. --- gdb/darwin-nat.c | 6 +++--- gdb/gnu-nat.c | 7 ------- gdb/inf-ptrace.c | 6 +++--- gdb/infcmd.c | 2 +- gdb/linux-nat.c | 12 +++++++++--- gdb/monitor.c | 4 ++-- gdb/nto-procfs.c | 14 +++++++------- gdb/procfs.c | 4 ++-- gdb/remote-m32r-sdi.c | 6 +++--- gdb/remote-sim.c | 20 ++++++++++---------- gdb/remote.c | 44 +++++++++++++++++++++++++++++++++----------- gdb/target-delegates.c | 28 ++++++++++++++++++++++++++++ gdb/target.c | 12 ++++++++++++ gdb/target.h | 8 ++++++++ gdb/windows-nat.c | 6 +++--- 15 files changed, 124 insertions(+), 55 deletions(-) diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c index e1acc05..30e968f 100644 --- a/gdb/darwin-nat.c +++ b/gdb/darwin-nat.c @@ -83,7 +83,7 @@ #define PTRACE(CMD, PID, ADDR, SIG) \ darwin_ptrace(#CMD, CMD, (PID), (ADDR), (SIG)) -static void darwin_stop (struct target_ops *self, ptid_t); +static void darwin_interrupt (struct target_ops *self, ptid_t); static void darwin_resume_to (struct target_ops *ops, ptid_t ptid, int step, enum gdb_signal signal); @@ -1198,7 +1198,7 @@ darwin_wait_to (struct target_ops *ops, } static void -darwin_stop (struct target_ops *self, ptid_t t) +darwin_interrupt (struct target_ops *self, ptid_t t) { struct inferior *inf = current_inferior (); @@ -2156,7 +2156,7 @@ _initialize_darwin_inferior (void) darwin_ops->to_wait = darwin_wait_to; darwin_ops->to_mourn_inferior = darwin_mourn_inferior; darwin_ops->to_kill = darwin_kill_inferior; - darwin_ops->to_stop = darwin_stop; + darwin_ops->to_interrupt = darwin_interrupt; darwin_ops->to_resume = darwin_resume_to; darwin_ops->to_thread_alive = darwin_thread_alive; darwin_ops->to_pid_to_str = darwin_pid_to_str; diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c index d830773..4753634 100644 --- a/gdb/gnu-nat.c +++ b/gdb/gnu-nat.c @@ -2271,12 +2271,6 @@ gnu_terminal_init (struct target_ops *self) child_terminal_init_with_pgrp (gnu_current_inf->pid); } -static void -gnu_stop (struct target_ops *self, ptid_t ptid) -{ - error (_("to_stop target function not implemented")); -} - static int gnu_thread_alive (struct target_ops *ops, ptid_t ptid) { @@ -2686,7 +2680,6 @@ gnu_target (void) t->to_mourn_inferior = gnu_mourn_inferior; t->to_thread_alive = gnu_thread_alive; t->to_pid_to_str = gnu_pid_to_str; - t->to_stop = gnu_stop; return t; } diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c index cd58dfb..17ba903 100644 --- a/gdb/inf-ptrace.c +++ b/gdb/inf-ptrace.c @@ -288,10 +288,10 @@ inf_ptrace_kill (struct target_ops *ops) target_mourn_inferior (); } -/* Stop the inferior. */ +/* Interrupt the inferior. */ static void -inf_ptrace_stop (struct target_ops *self, ptid_t ptid) +inf_ptrace_interrupt (struct target_ops *self, ptid_t ptid) { /* Send a SIGINT to the process group. This acts just like the user typed a ^C on the controlling terminal. Note that using a @@ -686,7 +686,7 @@ inf_ptrace_target (void) t->to_mourn_inferior = inf_ptrace_mourn_inferior; t->to_thread_alive = inf_ptrace_thread_alive; t->to_pid_to_str = inf_ptrace_pid_to_str; - t->to_stop = inf_ptrace_stop; + t->to_interrupt = inf_ptrace_interrupt; t->to_xfer_partial = inf_ptrace_xfer_partial; #if defined (PT_IO) && defined (PIOD_READ_AUXV) t->to_auxv_parse = inf_ptrace_auxv_parse; diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 94d87214..6ad8494 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -2853,7 +2853,7 @@ interrupt_target_1 (int all_threads) ptid = minus_one_ptid; else ptid = inferior_ptid; - target_stop (ptid); + target_interrupt (ptid); /* Tag the thread as having been explicitly requested to stop, so other parts of gdb know not to resume this thread automatically, diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 9de291e..d8001f9 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -4778,10 +4778,16 @@ linux_nat_stop_lwp (struct lwp_info *lwp, void *data) static void linux_nat_stop (struct target_ops *self, ptid_t ptid) { - if (target_is_non_stop_p ()) + iterate_over_lwps (ptid, linux_nat_stop_lwp, NULL); +} + +static void +linux_nat_interrupt (struct target_ops *self, ptid_t ptid) +{ + if (non_stop) iterate_over_lwps (ptid, linux_nat_stop_lwp, NULL); else - linux_ops->to_stop (linux_ops, ptid); + linux_ops->to_interrupt (linux_ops, ptid); } static void @@ -4884,8 +4890,8 @@ linux_nat_add_target (struct target_ops *t) super_close = t->to_close; t->to_close = linux_nat_close; - /* Methods for non-stop support. */ t->to_stop = linux_nat_stop; + t->to_interrupt = linux_nat_interrupt; t->to_supports_multi_process = linux_nat_supports_multi_process; diff --git a/gdb/monitor.c b/gdb/monitor.c index 548dae3..e47d479 100644 --- a/gdb/monitor.c +++ b/gdb/monitor.c @@ -2267,7 +2267,7 @@ monitor_load (struct target_ops *self, const char *args, int from_tty) } static void -monitor_stop (struct target_ops *self, ptid_t ptid) +monitor_interrupt (struct target_ops *self, ptid_t ptid) { monitor_debug ("MON stop\n"); if ((current_monitor->flags & MO_SEND_BREAK_ON_STOP) != 0) @@ -2375,7 +2375,7 @@ init_base_monitor_ops (void) monitor_ops.to_load = monitor_load; monitor_ops.to_create_inferior = monitor_create_inferior; monitor_ops.to_mourn_inferior = monitor_mourn_inferior; - monitor_ops.to_stop = monitor_stop; + monitor_ops.to_interrupt = monitor_interrupt; monitor_ops.to_rcmd = monitor_rcmd; monitor_ops.to_log_command = serial_log_command; monitor_ops.to_thread_alive = monitor_thread_alive; diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c index 7312060..c318f19 100644 --- a/gdb/nto-procfs.c +++ b/gdb/nto-procfs.c @@ -692,20 +692,20 @@ Give up (and stop debugging it)? "))) /* The user typed ^C twice. */ static void -nto_interrupt_twice (int signo) +nto_handle_sigint_twice (int signo) { signal (signo, ofunc); interrupt_query (); - signal (signo, nto_interrupt_twice); + signal (signo, nto_handle_sigint_twice); } static void -nto_interrupt (int signo) +nto_handle_sigint (int signo) { /* If this doesn't work, try more severe steps. */ - signal (signo, nto_interrupt_twice); + signal (signo, nto_handle_sigint_twice); - target_stop (inferior_ptid); + target_interrupt (inferior_ptid); } static ptid_t @@ -733,7 +733,7 @@ procfs_wait (struct target_ops *ops, devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); while (!(status.flags & _DEBUG_FLAG_ISTOP)) { - ofunc = (void (*)()) signal (SIGINT, nto_interrupt); + ofunc = (void (*)()) signal (SIGINT, nto_handle_sigint); sigwaitinfo (&set, &info); signal (SIGINT, ofunc); devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); @@ -1444,7 +1444,7 @@ init_procfs_targets (void) t->to_thread_alive = procfs_thread_alive; t->to_update_thread_list = procfs_update_thread_list; t->to_pid_to_str = procfs_pid_to_str; - t->to_stop = procfs_stop; + t->to_interrupt = procfs_interrupt; t->to_have_continuable_watchpoint = 1; t->to_extra_thread_info = nto_extra_thread_info; diff --git a/gdb/procfs.c b/gdb/procfs.c index b62539f..e540e2a 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -194,7 +194,7 @@ procfs_target (void) t->to_xfer_partial = procfs_xfer_partial; t->to_pass_signals = procfs_pass_signals; t->to_files_info = procfs_files_info; - t->to_stop = procfs_stop; + t->to_interrupt = procfs_interrupt; t->to_update_thread_list = procfs_update_thread_list; t->to_thread_alive = procfs_thread_alive; @@ -4204,7 +4204,7 @@ procfs_files_info (struct target_ops *ignore) kill(SIGINT) to the child's process group. */ static void -procfs_stop (struct target_ops *self, ptid_t ptid) +procfs_interrupt (struct target_ops *self, ptid_t ptid) { kill (-inferior_process_group (), SIGINT); } diff --git a/gdb/remote-m32r-sdi.c b/gdb/remote-m32r-sdi.c index 01cb5b6..b246cd9 100644 --- a/gdb/remote-m32r-sdi.c +++ b/gdb/remote-m32r-sdi.c @@ -1407,10 +1407,10 @@ m32r_load (struct target_ops *self, const char *args, int from_tty) } static void -m32r_stop (struct target_ops *self, ptid_t ptid) +m32r_interrupt (struct target_ops *self, ptid_t ptid) { if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "m32r_stop()\n"); + fprintf_unfiltered (gdb_stdlog, "m32r_interrupt()\n"); send_cmd (SDI_STOP_CPU); @@ -1664,7 +1664,7 @@ init_m32r_ops (void) m32r_ops.to_load = m32r_load; m32r_ops.to_create_inferior = m32r_create_inferior; m32r_ops.to_mourn_inferior = m32r_mourn_inferior; - m32r_ops.to_stop = m32r_stop; + m32r_ops.to_interrupt = m32r_interrupt; m32r_ops.to_log_command = serial_log_command; m32r_ops.to_thread_alive = m32r_thread_alive; m32r_ops.to_pid_to_str = m32r_pid_to_str; diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c index fd2fd58..766356a 100644 --- a/gdb/remote-sim.c +++ b/gdb/remote-sim.c @@ -87,7 +87,7 @@ static void gdbsim_files_info (struct target_ops *target); static void gdbsim_mourn_inferior (struct target_ops *target); -static void gdbsim_stop (struct target_ops *self, ptid_t ptid); +static void gdbsim_interrupt (struct target_ops *self, ptid_t ptid); void simulator_command (char *args, int from_tty); @@ -888,17 +888,17 @@ gdbsim_resume (struct target_ops *ops, error (_("The program is not being run.")); } -/* Notify the simulator of an asynchronous request to stop. +/* Notify the simulator of an asynchronous request to interrupt. - The simulator shall ensure that the stop request is eventually + The simulator shall ensure that the interrupt request is eventually delivered to the simulator. If the call is made while the - simulator is not running then the stop request is processed when + simulator is not running then the interrupt request is processed when the simulator is next resumed. For simulators that do not support this operation, just abort. */ static int -gdbsim_stop_inferior (struct inferior *inf, void *arg) +gdbsim_interrupt_inferior (struct inferior *inf, void *arg) { struct sim_inferior_data *sim_data = get_sim_inferior_data (inf, SIM_INSTANCE_NEEDED); @@ -918,13 +918,13 @@ gdbsim_stop_inferior (struct inferior *inf, void *arg) } static void -gdbsim_stop (struct target_ops *self, ptid_t ptid) +gdbsim_interrupt (struct target_ops *self, ptid_t ptid) { struct sim_inferior_data *sim_data; if (ptid_equal (ptid, minus_one_ptid)) { - iterate_over_inferiors (gdbsim_stop_inferior, NULL); + iterate_over_inferiors (gdbsim_interrupt_inferior, NULL); } else { @@ -934,7 +934,7 @@ gdbsim_stop (struct target_ops *self, ptid_t ptid) error (_("Can't stop pid %d. No inferior found."), ptid_get_pid (ptid)); - gdbsim_stop_inferior (inf, NULL); + gdbsim_interrupt_inferior (inf, NULL); } } @@ -962,7 +962,7 @@ gdb_os_poll_quit (host_callback *p) static void gdbsim_cntrl_c (int signo) { - gdbsim_stop (NULL, minus_one_ptid); + gdbsim_interrupt (NULL, minus_one_ptid); } static ptid_t @@ -1320,7 +1320,7 @@ init_gdbsim_ops (void) gdbsim_ops.to_load = gdbsim_load; gdbsim_ops.to_create_inferior = gdbsim_create_inferior; gdbsim_ops.to_mourn_inferior = gdbsim_mourn_inferior; - gdbsim_ops.to_stop = gdbsim_stop; + gdbsim_ops.to_interrupt = gdbsim_interrupt; gdbsim_ops.to_thread_alive = gdbsim_thread_alive; gdbsim_ops.to_pid_to_str = gdbsim_pid_to_str; gdbsim_ops.to_stratum = process_stratum; diff --git a/gdb/remote.c b/gdb/remote.c index 0bf8b87..c1b7fd4 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -4991,11 +4991,12 @@ async_cleanup_sigint_signal_handler (void *dummy) packet. */ static void (*ofunc) (int); -/* The command line interface's stop routine. This function is installed - as a signal handler for SIGINT. The first time a user requests a - stop, we call remote_stop to send a break or ^C. If there is no +/* The command line interface's interrupt routine. This function is installed + as a signal handler for SIGINT. The first time a user requests an + interrupt, we call remote_interrupt to send a break or ^C. If there is no response from the target (it didn't stop when the user requested it), we ask the user if he'd like to detach from the target. */ + static void sync_remote_interrupt (int signo) { @@ -5066,12 +5067,12 @@ remote_stop_ns (ptid_t ptid) error (_("Stopping %s failed: %s"), target_pid_to_str (ptid), rs->buf); } -/* All-stop version of target_stop. Sends a break or a ^C to stop the - remote target. It is undefined which thread of which process - reports the stop. */ +/* All-stop version of target_interrupt. Sends a break or a ^C to + interrupt the remote target. It is undefined which thread of which + process reports the interrupt. */ static void -remote_stop_as (ptid_t ptid) +remote_interrupt_as (ptid_t ptid) { struct remote_state *rs = get_remote_state (); @@ -5087,9 +5088,7 @@ remote_stop_as (ptid_t ptid) send_interrupt_sequence (); } -/* This is the generic stop called via the target vector. When a target - interrupt is requested, either by the command line or the GUI, we - will eventually end up here. */ +/* Implement the to_stop function for the remote targets. */ static void remote_stop (struct target_ops *self, ptid_t ptid) @@ -5100,7 +5099,29 @@ remote_stop (struct target_ops *self, ptid_t ptid) if (non_stop) remote_stop_ns (ptid); else - remote_stop_as (ptid); + { + /* We don't currently have a way to transparently pause the + remote target in all-stop mode. Interrupt it instead. */ + remote_interrupt_as (ptid); + } +} + +/* Implement the to_interrupt function for the remote targets. */ + +static void +remote_interrupt (struct target_ops *self, ptid_t ptid) +{ + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n"); + + if (non_stop) + { + /* We don't currently have a way to ^C the remote target in + non-stop mode. Stop it (with no signal) instead. */ + remote_stop_ns (ptid); + } + else + remote_interrupt_as (ptid); } /* Ask the user what to do when an interrupt is received. */ @@ -11700,6 +11721,7 @@ Specify the serial device it is connected to\n\ remote_ops.to_extra_thread_info = remote_threads_extra_info; 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_xfer_partial = remote_xfer_partial; remote_ops.to_rcmd = remote_rcmd; remote_ops.to_log_command = serial_log_command; diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c index 8a92acf..054ad32 100644 --- a/gdb/target-delegates.c +++ b/gdb/target-delegates.c @@ -1537,6 +1537,30 @@ debug_stop (struct target_ops *self, ptid_t arg1) } static void +delegate_interrupt (struct target_ops *self, ptid_t arg1) +{ + self = self->beneath; + self->to_interrupt (self, arg1); +} + +static void +tdefault_interrupt (struct target_ops *self, ptid_t arg1) +{ +} + +static void +debug_interrupt (struct target_ops *self, ptid_t arg1) +{ + fprintf_unfiltered (gdb_stdlog, "-> %s->to_interrupt (...)\n", debug_target.to_shortname); + debug_target.to_interrupt (&debug_target, arg1); + fprintf_unfiltered (gdb_stdlog, "<- %s->to_interrupt (", debug_target.to_shortname); + target_debug_print_struct_target_ops_p (&debug_target); + fputs_unfiltered (", ", gdb_stdlog); + target_debug_print_ptid_t (arg1); + fputs_unfiltered (")\n", gdb_stdlog); +} + +static void delegate_rcmd (struct target_ops *self, const char *arg1, struct ui_file *arg2) { self = self->beneath; @@ -4016,6 +4040,8 @@ install_delegators (struct target_ops *ops) ops->to_thread_name = delegate_thread_name; if (ops->to_stop == NULL) ops->to_stop = delegate_stop; + if (ops->to_interrupt == NULL) + ops->to_interrupt = delegate_interrupt; if (ops->to_rcmd == NULL) ops->to_rcmd = delegate_rcmd; if (ops->to_pid_to_exec_file == NULL) @@ -4253,6 +4279,7 @@ install_dummy_methods (struct target_ops *ops) ops->to_extra_thread_info = tdefault_extra_thread_info; ops->to_thread_name = tdefault_thread_name; ops->to_stop = tdefault_stop; + ops->to_interrupt = tdefault_interrupt; ops->to_rcmd = default_rcmd; ops->to_pid_to_exec_file = tdefault_pid_to_exec_file; ops->to_log_command = tdefault_log_command; @@ -4402,6 +4429,7 @@ init_debug_target (struct target_ops *ops) ops->to_extra_thread_info = debug_extra_thread_info; ops->to_thread_name = debug_thread_name; ops->to_stop = debug_stop; + ops->to_interrupt = debug_interrupt; ops->to_rcmd = debug_rcmd; ops->to_pid_to_exec_file = debug_pid_to_exec_file; ops->to_log_command = debug_log_command; diff --git a/gdb/target.c b/gdb/target.c index ab6c977..2262131 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -3244,6 +3244,18 @@ target_stop (ptid_t ptid) (*current_target.to_stop) (¤t_target, ptid); } +void +target_interrupt (ptid_t ptid) +{ + if (!may_stop) + { + warning (_("May not interrupt or stop the target, ignoring attempt")); + return; + } + + (*current_target.to_interrupt) (¤t_target, ptid); +} + /* See target/target.h. */ void diff --git a/gdb/target.h b/gdb/target.h index 2663db5..6c57a69 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -606,6 +606,8 @@ struct target_ops TARGET_DEFAULT_RETURN (NULL); void (*to_stop) (struct target_ops *, ptid_t) TARGET_DEFAULT_IGNORE (); + void (*to_interrupt) (struct target_ops *, ptid_t) + TARGET_DEFAULT_IGNORE (); void (*to_rcmd) (struct target_ops *, const char *command, struct ui_file *output) TARGET_DEFAULT_FUNC (default_rcmd); @@ -1630,6 +1632,12 @@ extern void target_update_thread_list (void); extern void target_stop (ptid_t ptid); +/* Interrupt the target just like the user typed a ^C on the + inferior's controlling terminal. (For instance, under Unix, this + should act like SIGINT). This function is asynchronous. */ + +extern void target_interrupt (ptid_t ptid); + /* Send the specified COMMAND to the target's monitor (shell,interpreter) for execution. The result of the query is placed in OUTBUF. */ diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index fd31083..46a378c 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -162,7 +162,7 @@ static int windows_initialization_done; #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x -static void windows_stop (struct target_ops *self, ptid_t); +static void windows_interrupt (struct target_ops *self, ptid_t); static int windows_thread_alive (struct target_ops *, ptid_t); static void windows_kill_inferior (struct target_ops *); @@ -2294,7 +2294,7 @@ windows_mourn_inferior (struct target_ops *ops) ^C on the controlling terminal. */ static void -windows_stop (struct target_ops *self, ptid_t ptid) +windows_interrupt (struct target_ops *self, ptid_t ptid) { DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n")); CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId)); @@ -2488,7 +2488,7 @@ windows_target (void) t->to_mourn_inferior = windows_mourn_inferior; t->to_thread_alive = windows_thread_alive; t->to_pid_to_str = windows_pid_to_str; - t->to_stop = windows_stop; + t->to_interrupt = windows_interrupt; t->to_pid_to_exec_file = windows_pid_to_exec_file; t->to_get_ada_task_ptid = windows_get_ada_task_ptid; t->to_get_tib_address = windows_get_tib_address;