GDBserver: ctrl-c after leader has exited
authorPedro Alves <palves@redhat.com>
Wed, 12 Nov 2014 11:17:39 +0000 (11:17 +0000)
committerPedro Alves <palves@redhat.com>
Wed, 12 Nov 2014 11:30:49 +0000 (11:30 +0000)
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.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.threads/leader-exit.c
gdb/testsuite/gdb.threads/leader-exit.exp

index 0940fa0358f4329f898e45a0da72a9d3b4b0c170..dbb8ce5d5184a11693054f7e0e5776a8f00f3114 100644 (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>
 
        PR server/17487
index 8776670b4966dd678d57f06a42328adc949162c6..d870f717ab5b363479f0426debe957509453246b 100644 (file)
@@ -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
index 37d82905cecdc5e46e4f445590edf4a4a40ed2ea..ae7c53c8f0abae8c65ee38e28662e3ed129bf722 100644 (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>
 
        * gdb.arch/i386-bp_permanent.c: New file.
index 287388a5d66acfc287a036807beb2ea5b32f5515..0df1adc932a4351e3973db17932f1028c32f1373 100644 (file)
@@ -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
index d213d557974ad095426b9a6ce649ab81113ccf0a..2d6b723ba2fa7713d183cc3ba7f0c4a9471005f4 100644 (file)
@@ -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
+    }
+}