diff options
author | Pedro Alves <palves@redhat.com> | 2015-03-15 19:35:26 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-03-19 12:38:05 +0000 |
commit | 8bf3b159e55b42bb084f9da1af400a285025618f (patch) | |
tree | 769fa2be997cc1a1ebff1ada69efe99cf1999c58 /gdb/testsuite/gdb.threads | |
parent | eb54c8bf087f434b0cb91b35e7cde68a69ac9193 (diff) | |
download | binutils-8bf3b159e55b42bb084f9da1af400a285025618f.zip binutils-8bf3b159e55b42bb084f9da1af400a285025618f.tar.gz binutils-8bf3b159e55b42bb084f9da1af400a285025618f.tar.bz2 |
gdbserver/Linux: unbreak thread event randomization
Wanting to make sure the new continue-pending-status.exp test tests
both cases of threads 2 and 3 reporting an event, I added counters to
the test, to make it FAIL if events for both threads aren't seen.
Assuming a well behaved backend, and given a reasonable number of
iterations, it should PASS.
However, running that against GNU/Linux gdbserver, I found that
surprisingly, that FAILed. GDBserver always reported the breakpoint
hit for the same thread.
Turns out that I broke gdbserver's thread event randomization
recently, with git commit 582511be ([gdbserver] linux-low.c: better
starvation avoidance, handle non-stop mode too). In that commit I
missed that the thread structure also has a status_pending_p field...
The end result was that count_events_callback always returns 0, and
then if no thread is stepping, select_event_lwp always returns the
event thread. IOW, no randomization is happening at all. Quite
curious how all the other changes in that patch were sufficient to fix
non-stop-fair-events.exp anyway even with that broken.
Tested on x86_64 Fedora 20, native and gdbserver.
gdb/gdbserver/ChangeLog:
2015-03-19 Pedro Alves <palves@redhat.com>
* linux-low.c (count_events_callback, select_event_lwp_callback):
Use the lwp's status_pending_p field, not the thread's.
gdb/testsuite/ChangeLog:
2015-03-19 Pedro Alves <palves@redhat.com>
* gdb.threads/continue-pending-status.exp (saw_thread_2)
(saw_thread_3): New globals.
(top level): Increment them when an event for the corresponding
thread is seen.
(no thread starvation): New test.
Diffstat (limited to 'gdb/testsuite/gdb.threads')
-rw-r--r-- | gdb/testsuite/gdb.threads/continue-pending-status.exp | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.threads/continue-pending-status.exp b/gdb/testsuite/gdb.threads/continue-pending-status.exp index ff73ce4..1f170f7 100644 --- a/gdb/testsuite/gdb.threads/continue-pending-status.exp +++ b/gdb/testsuite/gdb.threads/continue-pending-status.exp @@ -56,6 +56,13 @@ proc get_current_thread {} { set attempts 20 +# These track whether we saw events for both threads 2 and 3. If the +# backend always returns the breakpoint hit for the same thread, then +# it fails to make sure threads aren't starved, and we'll fail the +# assert after the loop. +set saw_thread_2 0 +set saw_thread_3 0 + for {set i 0} {$i < $attempts} {incr i} { with_test_prefix "attempt $i" { gdb_test "b $srcfile:$break_line" \ @@ -71,8 +78,10 @@ for {set i 0} {$i < $attempts} {incr i} { # the resume and go straight to consuming the pending event. set thread [get_current_thread] if {$thread == 2} { + incr saw_thread_2 set thread 3 } else { + incr saw_thread_3 set thread 2 } gdb_test "thread $thread" \ @@ -108,3 +117,8 @@ for {set i 0} {$i < $attempts} {incr i} { } } } + +verbose -log "saw_thread_2=$saw_thread_2" +verbose -log "saw_thread_3=$saw_thread_3" + +gdb_assert {$saw_thread_2 > 0 && $saw_thread_3 > 0} "no thread starvation" |