Fix lwp_suspend/unsuspend imbalance in linux_wait_1
authorAntoine Tremblay <antoine.tremblay@ericsson.com>
Wed, 31 Aug 2016 17:46:22 +0000 (13:46 -0400)
committerAntoine Tremblay <antoine.tremblay@ericsson.com>
Wed, 31 Aug 2016 17:46:22 +0000 (13:46 -0400)
This patch fixes imbalanced lwp_suspend/unsuspend calls caused by the
premature choosing of another event for fairness.

select_event_lwp would switch the event before a call to
unsuspend_all_lwps, thus it would be called with the wrong event.

This caused an assertion failure: unsuspend LWP xx, suspended=-1 when
testing  gdb.threads/non-stop-fair-events.exp with ARM range stepping in
GDBServer.

This patch moves the switch of event after the unsuspend/unstop calls.

No regressions, tested on ubuntu 14.04 ARMv7 and x86.
With gdbserver-native.

gdb/gdbserver/ChangeLog:

* linux-low.c (linux_wait_1): Move event switch after unsuspend_lwps.

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

index af0140f0ed469a2835fbd06f8039e71c976cbbce..4dc2e451ea6dd93495b3b160d33636a75033ff53 100644 (file)
@@ -1,3 +1,7 @@
+2016-08-31  Antoine Tremblay  <antoine.tremblay@ericsson.com>
+
+       * linux-low.c (linux_wait_1): Move event switch after unsuspend_lwps.
+
 2016-08-25  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
 
        PR server/20491
index 45061ac2566880e11c1d4e6621765efa18b79e1e..cdff436cffbe5dda55dae7bd9da1eb2b2ac1e23a 100644 (file)
@@ -3771,24 +3771,6 @@ linux_wait_1 (ptid_t ptid,
       if (!non_stop)
        stop_all_lwps (0, NULL);
 
-      /* If we're not waiting for a specific LWP, choose an event LWP
-        from among those that have had events.  Giving equal priority
-        to all LWPs that have had events helps prevent
-        starvation.  */
-      if (ptid_equal (ptid, minus_one_ptid))
-       {
-         event_child->status_pending_p = 1;
-         event_child->status_pending = w;
-
-         select_event_lwp (&event_child);
-
-         /* current_thread and event_child must stay in sync.  */
-         current_thread = get_lwp_thread (event_child);
-
-         event_child->status_pending_p = 0;
-         w = event_child->status_pending;
-       }
-
       if (step_over_finished)
        {
          if (!non_stop)
@@ -3813,6 +3795,25 @@ linux_wait_1 (ptid_t ptid,
            }
        }
 
+      /* If we're not waiting for a specific LWP, choose an event LWP
+        from among those that have had events.  Giving equal priority
+        to all LWPs that have had events helps prevent
+        starvation.  */
+      if (ptid_equal (ptid, minus_one_ptid))
+       {
+         event_child->status_pending_p = 1;
+         event_child->status_pending = w;
+
+         select_event_lwp (&event_child);
+
+         /* current_thread and event_child must stay in sync.  */
+         current_thread = get_lwp_thread (event_child);
+
+         event_child->status_pending_p = 0;
+         w = event_child->status_pending;
+       }
+
+
       /* Stabilize threads (move out of jump pads).  */
       if (!non_stop)
        stabilize_threads ();