aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine Tremblay <antoine.tremblay@ericsson.com>2016-08-31 13:46:22 -0400
committerAntoine Tremblay <antoine.tremblay@ericsson.com>2016-08-31 13:46:22 -0400
commit3aa5cfa0d1cdbbd839884302535da28ca8c8b00d (patch)
treeede1cd2e8206a76c94b6c4b75150954c4e7e58bf
parentf99bd5f2c1e6b545a0a6cfb3b13f79deea84098e (diff)
downloadgdb-3aa5cfa0d1cdbbd839884302535da28ca8c8b00d.zip
gdb-3aa5cfa0d1cdbbd839884302535da28ca8c8b00d.tar.gz
gdb-3aa5cfa0d1cdbbd839884302535da28ca8c8b00d.tar.bz2
Fix lwp_suspend/unsuspend imbalance in linux_wait_1
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.
-rw-r--r--gdb/gdbserver/ChangeLog4
-rw-r--r--gdb/gdbserver/linux-low.c37
2 files changed, 23 insertions, 18 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index af0140f..4dc2e45 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -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
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 45061ac..cdff436 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -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 ();