8601984ddb2eaadbdf3c10e1f4f4092886fea3f2
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.threads / non-stop-fair-events.exp
1 # Copyright (C) 2014-2019 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 # Test that GDB in non-stop mode gives roughly equal priority to
17 # events of all threads.
18
19 standard_testfile
20 set executable ${testfile}
21
22 if [target_info exists gdb,nosignals] {
23 verbose "Skipping ${testfile}.exp because of nosignals."
24 return -1
25 }
26
27 set options { "additional_flags=-DTIMEOUT=$timeout" debug pthreads }
28 if {[prepare_for_testing "failed to prepare" $testfile $srcfile $options] == -1} {
29 return -1
30 }
31
32 gdb_test_no_output "set non-stop on"
33
34 if ![runto_main] {
35 return -1
36 }
37
38 # We want "handle print", to make sure the target backend reports the
39 # signal to the run control core.
40 gdb_test "handle SIGUSR1 print nostop pass" ""
41
42 # Get current value of VAR from the inferior. TEST is used as test
43 # message.
44
45 proc get_value {var test} {
46 global expect_out
47 global gdb_prompt
48 global decimal
49
50 set value -1
51 gdb_test_multiple "print $var" "$test" {
52 -re ".*= ($decimal).*\r\n$gdb_prompt $" {
53 set value $expect_out(1,string)
54 pass "$test"
55 }
56 }
57 return ${value}
58 }
59
60 set NUM_THREADS [get_value "num_threads" "get num_threads"]
61
62 # Account for the main thread.
63 incr NUM_THREADS
64
65 # Probe for displaced stepping support. We're stopped at the main
66 # breakpoint. If displaced stepping is supported, we should see
67 # related debug output.
68 set displaced_stepping_enabled 0
69 set msg "check displaced-stepping"
70 gdb_test_no_output "set debug displaced 1"
71 gdb_test_multiple "next" $msg {
72 -re "displaced pc to.*$gdb_prompt $" {
73 set displaced_stepping_enabled 1
74 }
75 -re ".*$gdb_prompt $" {
76 }
77 }
78 gdb_test_no_output "set debug displaced 0"
79
80 # Run threads to their start positions. This prepares for a new test
81 # sequence.
82
83 proc restart {} {
84 global gdb_prompt
85 global NUM_THREADS
86
87 delete_breakpoints
88
89 gdb_test "print got_sig = 0" " = 0"
90
91 gdb_breakpoint [gdb_get_line_number "set thread breakpoint here"]
92 gdb_breakpoint [gdb_get_line_number "set kill breakpoint here"]
93
94 set test "continue -a&"
95 gdb_test_multiple $test $test {
96 -re "Continuing.\r\n$gdb_prompt " {
97 pass $test
98 }
99 }
100
101 for {set i 1} { $i <= $NUM_THREADS } { incr i } {
102 set test "thread $i restarted"
103 gdb_test_multiple "" $test {
104 -re "breakpoint here" {
105 # The prompt was already matched in the "continue &"
106 # test above. We're now consuming asynchronous output
107 # that comes after the prompt.
108 pass $test
109 }
110 }
111 }
112
113 delete_breakpoints
114 }
115
116 # Run command and wait for the prompt, without end anchor.
117
118 proc gdb_test_no_anchor {cmd} {
119 global gdb_prompt
120
121 gdb_test_multiple $cmd $cmd {
122 -re "$gdb_prompt " {
123 pass $cmd
124 }
125 }
126 }
127
128 # Enable/disable debugging.
129
130 proc enable_debug {enable} {
131
132 # Comment out to debug problems with the test.
133 return
134
135 gdb_test_no_anchor "set debug infrun $enable"
136 gdb_test_no_anchor "set debug displaced $enable"
137 }
138
139 # The test proper. SIGNAL_THREAD is the thread that has been elected
140 # to receive the SIGUSR1 signal.
141
142 proc test {signal_thread} {
143 global gdb_prompt
144 global NUM_THREADS
145 global timeout
146 global displaced_stepping_enabled
147
148 with_test_prefix "signal_thread=$signal_thread" {
149 restart
150
151 # Set all threads stepping the infinite loop line in parallel.
152 for {set i 2} { $i <= $NUM_THREADS } { incr i } {
153 gdb_test "thread $i" \
154 "child_function.*set thread breakpoint here.*" \
155 "switch to thread $i to step it"
156
157 if {$i == $signal_thread} {
158 gdb_test "print signal_thread = self" " = .*"
159 }
160
161 gdb_test "step&" "" "set $i thread stepping"
162 }
163
164 gdb_test "thread 1" "Switching to .*" \
165 "switch to the main thread to queue signal"
166
167 # Let the main thread queue the signal.
168 gdb_breakpoint "loop_broke"
169
170 enable_debug 1
171
172 # On software single-step targets that don't support displaced
173 # stepping, threads keep hitting each others' single-step
174 # breakpoints, and then GDB needs to pause all threads to step
175 # past those. The end result is that progress in the main
176 # thread will be slower and it may take a bit longer for the
177 # signal to be queued; bump the timeout.
178 if {!$displaced_stepping_enabled && ![can_hardware_single_step]} {
179 # The more threads we have, the longer it takes.
180 set factor $NUM_THREADS
181 } else {
182 set factor 1
183 }
184 with_timeout_factor $factor {
185 gdb_test "print timeout = $timeout" " = $timeout" \
186 "set timeout in the inferior"
187
188 set saw_continuing 0
189 set test "continue &"
190 gdb_test_multiple $test $test {
191 -re "Continuing.\r\n" {
192 set saw_continuing 1
193 exp_continue
194 }
195 -re "$gdb_prompt " {
196 gdb_assert $saw_continuing $test
197 }
198 -re "infrun:" {
199 exp_continue
200 }
201 }
202
203 set gotit 0
204
205 # Wait for all threads to finish their steps, and for the main
206 # thread to hit the breakpoint.
207 for {set i 1} { $i <= $NUM_THREADS } { incr i } {
208 set test "thread $i broke out of loop"
209 set gotit 0
210 gdb_test_multiple "" $test {
211 -re "loop_broke" {
212 # The prompt was already matched in the "continue
213 # &" test above. We're now consuming asynchronous
214 # output that comes after the prompt.
215 set gotit 1
216 pass $test
217 }
218 -re "infrun:" {
219 exp_continue
220 }
221 }
222 if {!$gotit} {
223 break
224 }
225 }
226 }
227
228 enable_debug 0
229
230 # It's helpful to have this in the log if the test ever
231 # happens to fail.
232 gdb_test "info threads"
233
234 return $gotit
235 }
236 }
237
238 # The kernel/debug API may always walk its thread list looking for the
239 # first with an event, resulting in giving priority to e.g. the thread
240 # with lowest kernel thread ID. So test once with the signal pending
241 # in each thread, except the main thread.
242 for {set i 2} { $i <= $NUM_THREADS } { incr i } {
243 if {![test $i]} {
244 # Avoid cascading timeouts, and bail out.
245 return
246 }
247 }
This page took 0.034143 seconds and 3 git commands to generate.