diff options
author | Pedro Alves <palves@redhat.com> | 2015-08-06 18:22:58 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-08-07 17:26:20 +0100 |
commit | bfedc46af315dc6484295699c35e05040d76d700 (patch) | |
tree | 8d40b327d379d576de014e255b096d2e5e32ae7e /gdb/remote.c | |
parent | d55007b58352c0b5fd2817e003b6dcf4e3ee4c07 (diff) | |
download | gdb-bfedc46af315dc6484295699c35e05040d76d700.zip gdb-bfedc46af315dc6484295699c35e05040d76d700.tar.gz gdb-bfedc46af315dc6484295699c35e05040d76d700.tar.bz2 |
Fix interrupt-noterm.exp on targets always in non-stop
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-08-07 Pedro Alves <palves@redhat.com>
* darwin-nat.c (darwin_stop): Rename to ...
(darwin_interrupt): ... this.
(_initialize_darwin_inferior): Adjust.
* gnu-nat.c (gnu_stop): Delete.
(gnu_target): 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.
* 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): Adjust.
(procfs_stop): Rename to ...
(procfs_interrupt): ... this.
(init_procfs_targets): Adjust.
* procfs.c (procfs_stop): Rename to ...
(procfs_interrupt): ... this.
(procfs_target): Adjust.
* 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) <to_interrupt>: New field.
(target_interrupt): New declaration.
* windows-nat.c (windows_stop): Rename to ...
(windows_interrupt): ... this.
* target-delegates.c: Regenerate.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r-- | gdb/remote.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/gdb/remote.c b/gdb/remote.c index 4b5eb8e..6d577d8 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -5215,11 +5215,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) { @@ -5290,12 +5291,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 (); @@ -5311,9 +5312,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) @@ -5324,7 +5323,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. */ @@ -12275,6 +12296,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_pid_to_exec_file = remote_pid_to_exec_file; |