From 78708b7c8ccc2138880217de9bd60eceff683f10 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 12 Nov 2014 11:17:39 +0000 Subject: [PATCH] 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 * 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 * gdb.threads/leader-exit.exp: Test sending ctrl-c works after the leader has exited. --- gdb/gdbserver/ChangeLog | 5 +++++ gdb/gdbserver/linux-low.c | 13 +++---------- gdb/testsuite/ChangeLog | 5 +++++ gdb/testsuite/gdb.threads/leader-exit.c | 3 ++- gdb/testsuite/gdb.threads/leader-exit.exp | 20 ++++++++++++++++++++ 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 0940fa0358f..dbb8ce5d518 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,8 @@ +2014-11-12 Pedro Alves + + * 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 PR server/17487 diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 8776670b496..d870f717ab5 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -4848,16 +4848,9 @@ linux_request_interrupt (void) { extern unsigned long signal_pid; - if (!ptid_equal (cont_thread, null_ptid) - && !ptid_equal (cont_thread, minus_one_ptid)) - { - int lwpid; - - lwpid = lwpid_of (current_thread); - kill_lwp (lwpid, SIGINT); - } - else - kill_lwp (signal_pid, SIGINT); + /* Send a SIGINT to the process group. This acts just like the user + typed a ^C on the controlling terminal. */ + kill (-signal_pid, SIGINT); } /* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 37d82905cec..ae7c53c8f0a 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-11-12 Pedro Alves + + * gdb.threads/leader-exit.exp: Test sending ctrl-c works after the + leader has exited. + 2014-11-12 Pedro Alves * gdb.arch/i386-bp_permanent.c: New file. diff --git a/gdb/testsuite/gdb.threads/leader-exit.c b/gdb/testsuite/gdb.threads/leader-exit.c index 287388a5d66..0df1adc932a 100644 --- a/gdb/testsuite/gdb.threads/leader-exit.c +++ b/gdb/testsuite/gdb.threads/leader-exit.c @@ -29,7 +29,8 @@ start (void *arg) i = pthread_join (main_thread, NULL); assert (i == 0); - return arg; /* break-here */ + sleep (10); /* break-here */ + return arg; } int diff --git a/gdb/testsuite/gdb.threads/leader-exit.exp b/gdb/testsuite/gdb.threads/leader-exit.exp index d213d557974..2d6b723ba2f 100644 --- a/gdb/testsuite/gdb.threads/leader-exit.exp +++ b/gdb/testsuite/gdb.threads/leader-exit.exp @@ -34,3 +34,23 @@ gdb_continue_to_breakpoint "break-here" ".* break-here .*" gdb_test "info threads" \ "\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" + +# 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 + } +} -- 2.30.2