GDBserver: ctrl-c after leader has exited

The target->request_interrupt callback implements the handling for
ctrl-c.  User types ctrl-c in GDB, GDB sends a \003 to the remote
target, and the remote targets stops the program with a SIGINT, just
like if the user typed ctrl-c in GDBserver's terminal.

The trouble is that using kill_lwp(signal_pid, SIGINT) sends the
SIGINT directly to the program's main thread.  If that thread has
exited already, then that kill won't do anything.

Instead, send the SIGINT to the process group, just like GDB
does (see inf-ptrace.c:inf_ptrace_stop).

gdb.threads/leader-exit.exp is extended to cover the scenario.  It
fails against GDBserver before the patch.

Tested on x86_64 Fedora 20, native and GDBserver.

gdb/gdbserver/
2014-11-12  Pedro Alves  <palves@redhat.com>

	* linux-low.c (linux_request_interrupt): Always send a SIGINT to
	the process group instead of to a specific LWP.

gdb/testsuite/
2014-11-12  Pedro Alves  <palves@redhat.com>

	* gdb.threads/leader-exit.exp: Test sending ctrl-c works after the
	leader has exited.
This commit is contained in:
Pedro Alves 2014-11-12 11:17:39 +00:00
parent 6218dc4bdb
commit 78708b7c8c
5 changed files with 35 additions and 11 deletions

View file

@ -1,3 +1,8 @@
2014-11-12 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_request_interrupt): Always send a SIGINT to
the process group instead of to a specific LWP.
2014-10-15 Pedro Alves <palves@redhat.com> 2014-10-15 Pedro Alves <palves@redhat.com>
PR server/17487 PR server/17487

View file

@ -4848,16 +4848,9 @@ linux_request_interrupt (void)
{ {
extern unsigned long signal_pid; extern unsigned long signal_pid;
if (!ptid_equal (cont_thread, null_ptid) /* Send a SIGINT to the process group. This acts just like the user
&& !ptid_equal (cont_thread, minus_one_ptid)) typed a ^C on the controlling terminal. */
{ kill (-signal_pid, SIGINT);
int lwpid;
lwpid = lwpid_of (current_thread);
kill_lwp (lwpid, SIGINT);
}
else
kill_lwp (signal_pid, SIGINT);
} }
/* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET /* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET

View file

@ -1,3 +1,8 @@
2014-11-12 Pedro Alves <palves@redhat.com>
* gdb.threads/leader-exit.exp: Test sending ctrl-c works after the
leader has exited.
2014-11-12 Pedro Alves <palves@redhat.com> 2014-11-12 Pedro Alves <palves@redhat.com>
* gdb.arch/i386-bp_permanent.c: New file. * gdb.arch/i386-bp_permanent.c: New file.

View file

@ -29,7 +29,8 @@ start (void *arg)
i = pthread_join (main_thread, NULL); i = pthread_join (main_thread, NULL);
assert (i == 0); assert (i == 0);
return arg; /* break-here */ sleep (10); /* break-here */
return arg;
} }
int int

View file

@ -34,3 +34,23 @@ gdb_continue_to_breakpoint "break-here" ".* break-here .*"
gdb_test "info threads" \ gdb_test "info threads" \
"\r\n\[ \t\]*Id\[ \t\]+Target\[ \t\]+Id\[ \t\]+Frame\[ \t\]*\r\n\\* 2 *Thread \[^\r\n\]* at \[^\r\n\]*" \ "\r\n\[ \t\]*Id\[ \t\]+Target\[ \t\]+Id\[ \t\]+Frame\[ \t\]*\r\n\\* 2 *Thread \[^\r\n\]* at \[^\r\n\]*" \
"Single thread has been left" "Single thread has been left"
# Test that ctrl-c works even if the leader has exited.
set test "continue for ctrl-c"
gdb_test_multiple "continue" $test {
-re "Continuing" {
pass $test
}
}
sleep 1
send_gdb "\003"
set test "caught interrupt"
gdb_test_multiple "" $test {
-re "Program received signal SIGINT.*$gdb_prompt $" {
pass $test
}
}