diff options
author | Antoine Tremblay <antoine.tremblay@ericsson.com> | 2016-08-31 13:46:22 -0400 |
---|---|---|
committer | Antoine Tremblay <antoine.tremblay@ericsson.com> | 2016-08-31 14:23:16 -0400 |
commit | 305a161d11c4b5801a0e135fec5d77f3d64f121f (patch) | |
tree | 691b755739f93292064c9bbc06f4c1aa664290ca /gdb | |
parent | 97f74bcefff073a352f57c2fb4cc3390eb251ed9 (diff) | |
download | gdb-305a161d11c4b5801a0e135fec5d77f3d64f121f.zip gdb-305a161d11c4b5801a0e135fec5d77f3d64f121f.tar.gz gdb-305a161d11c4b5801a0e135fec5d77f3d64f121f.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.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 37 |
2 files changed, 23 insertions, 18 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index aecc0a9..a2031bf 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 (); |