gdbserver: fix killed-outside.exp
authorPedro Alves <palves@redhat.com>
Mon, 30 Nov 2015 16:05:23 +0000 (16:05 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 30 Nov 2015 18:41:26 +0000 (18:41 +0000)
killed-outside.exp regresses with "maint set target-non-stop on".  The
logs show:

 (gdb) continue
 Continuing.
 infrun: clear_proceed_status_thread (Thread 9028.9028)
 infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT)
 infrun: proceed: resuming Thread 9028.9028
 Sending packet: $Z0,3615a03966,1#4b...  Notification received: Stop:X9;process:2344
 Packet received: E01
 Sending packet: $Z0,3615a13970,1#47...Packet received: E01
 Sending packet: $Z0,3615a14891,1#4a...Packet received: E01
 infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 9028.9028] at 0x4005e4
 Sending packet: $vCont;c:p2344.2344#1a...Packet received: E.target not running.
 Sending packet: $qXfer:threads:read::0,fff#03...Packet received: l<threads>\n</threads>\n
 Sending packet: $vStopped#55...Packet received: OK
 Unexpected vCont reply in non-stop mode: E.target not running.
 (gdb) remote_async_inferior_event_handler
 infrun: target_wait (-1.0.0, status) =
 infrun:   9028.0.0 [process 9028],
 infrun:   status->kind = signalled, signal = GDB_SIGNAL_KILL
 infrun: TARGET_WAITKIND_SIGNALLED

 Program terminated with signal SIGKILL, Killed.
 The program no longer exists.
 infrun: stop_waiting
 infrun: clear_step_over_info
 infrun: stop_all_threads
 remote_thread_exit_events(1)

Note the "Unexpected vCont reply" error.

I traced it to a problem in status_pending_p_callback.  It resumes an
LWP when it shouldn't.

gdb/gdbserver/ChangeLog:
2015-11-30  Pedro Alves  <palves@redhat.com>

* linux-low.c (thread_still_has_status_pending_p): Don't check
vCont;t here.
(lwp_resumed): New function.
(status_pending_p_callback): Return early if the LWP is not
supposed to be resumed.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c

index 2d0489968021957ddcf3bc6d2eb6dcd1f7856115..bc09844a666eed9e2e9569dce7687aae9f339eed 100644 (file)
@@ -1,3 +1,11 @@
+2015-11-30  Pedro Alves  <palves@redhat.com>
+
+       * linux-low.c (thread_still_has_status_pending_p): Don't check
+       vCont;t here.
+       (lwp_resumed): New function.
+       (status_pending_p_callback): Return early if the LWP is not
+       supposed to be resumed.
+
 2015-11-30  Pedro Alves  <palves@redhat.com>
 
        * linux-low.c (handle_extended_wait): Assert that the LWP's
index cde59a72925e0458ea8f2a656d7f769f5108fdc5..07cb83120d310570cbbef4c7d409426c00f3f034 100644 (file)
@@ -1525,12 +1525,6 @@ thread_still_has_status_pending_p (struct thread_info *thread)
   if (!lp->status_pending_p)
     return 0;
 
-  /* If we got a `vCont;t', but we haven't reported a stop yet, do
-     report any status pending the LWP may have.  */
-  if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
-    return 0;
-
   if (thread->last_resume_kind != resume_stop
       && (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
          || lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT))
@@ -1587,6 +1581,26 @@ thread_still_has_status_pending_p (struct thread_info *thread)
   return 1;
 }
 
+/* Returns true if LWP is resumed from the client's perspective.  */
+
+static int
+lwp_resumed (struct lwp_info *lwp)
+{
+  struct thread_info *thread = get_lwp_thread (lwp);
+
+  if (thread->last_resume_kind != resume_stop)
+    return 1;
+
+  /* Did gdb send us a `vCont;t', but we haven't reported the
+     corresponding stop to gdb yet?  If so, the thread is still
+     resumed/running from gdb's perspective.  */
+  if (thread->last_resume_kind == resume_stop
+      && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+    return 1;
+
+  return 0;
+}
+
 /* Return 1 if this lwp has an interesting status pending.  */
 static int
 status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
@@ -1600,6 +1614,9 @@ status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
   if (!ptid_match (ptid_of (thread), ptid))
     return 0;
 
+  if (!lwp_resumed (lp))
+    return 0;
+
   if (lp->status_pending_p
       && !thread_still_has_status_pending_p (thread))
     {