]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/testsuite/gdb.multi/tids.exp
Fix "thread apply $conv_var" and misc other related problems
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.multi / tids.exp
CommitLineData
5d5658a1
PA
1# Copyright 2015-2016 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 thread ID parsing and display.
17
18load_lib gdb-python.exp
19
20standard_testfile
21
22# Multiple inferiors are needed, therefore both native and extended
23# gdbserver modes are supported. Only non-extended gdbserver is not
24# supported.
25if [target_info exists use_gdb_stub] {
26 untested ${testfile}.exp
27 return
28}
29
30if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} {pthreads debug}] } {
31 return -1
32}
33
34clean_restart ${testfile}
35
36if { ![runto_main] } then {
37 return -1
38}
39
40# Issue "thread apply TID_LIST p 1234" and expect EXP_TID_LIST (a list
41# of thread ids) to be displayed.
42proc thread_apply {tid_list exp_tid_list {message ""}} {
43 global decimal
44 set any "\[^\r\n\]*"
45 set expected [string_to_regexp $exp_tid_list]
46
47 set r ""
48 foreach tid $expected {
49 append r "\[\r\n\]+"
50 append r "Thread $tid $any:\r\n"
51 append r "\\$$decimal = 1234"
52 }
53
54 set cmd "thread apply $tid_list"
55 if {$message == ""} {
56 set message $cmd
57 }
58 gdb_test "$cmd p 1234" $r $message
59}
60
61# Issue "info threads TID_LIST" and expect EXP_TID_LIST (a list of
62# thread ids) to be displayed.
63proc info_threads {tid_list exp_tid_list {message ""}} {
64 set any "\[^\r\n\]*"
65 set expected [string_to_regexp $exp_tid_list]
66 set r [join $expected " ${any}\r\n${any} "]
67 set r "${any} $r ${any}"
68 set cmd "info threads $tid_list"
69 if {$message == ""} {
70 set message $cmd
71 }
72 gdb_test $cmd $r $message
73}
74
75# Issue "info threads TID_LIST" and expect INFO_THR output. Then
76# issue "thread apply TID_LIST" and expect THR_APPLY output. If
77# THR_APPLY is omitted, INFO_THR is expected instead.
78proc thr_apply_info_thr {tid_list info_thr {thr_apply ""}} {
79 if {$thr_apply == ""} {
80 set thr_apply $info_thr
81 }
82
83 info_threads $tid_list $info_thr
84 thread_apply $tid_list $thr_apply
85}
86
87# Issue both "info threads TID_LIST" and "thread apply TID_LIST" and
88# expect both commands to error out with EXP_ERROR.
89proc thr_apply_info_thr_error {tid_list exp_error} {
90 gdb_test "info threads $tid_list" \
91 $exp_error
92
3f5b7598 93 gdb_test "thread apply $tid_list" \
5d5658a1
PA
94 $exp_error \
95 "thread apply $tid_list"
96}
97
98# Issue both "info threads TID_LIST" and "thread apply TID_LIST" and
99# expect the command to error out with "Invalid thread ID: $EXPECTED".
3f5b7598
PA
100# EXPECTED is a literal string, not a regexp. If EXPECTED is omitted,
101# TID_LIST is expected instead.
102proc thr_apply_info_thr_invalid {tid_list {expected ""}} {
103 if {$expected == ""} {
104 set expected $tid_list
105 }
5d5658a1
PA
106 set expected [string_to_regexp $expected]
107 gdb_test "info threads $tid_list" \
108 "Invalid thread ID: $expected"
109
110 gdb_test "thread apply $tid_list p 1234" \
111 "Invalid thread ID: $expected p 1234" \
112 "thread apply $tid_list"
113}
114
115# "info threads" while there's only inferior 1 should show
116# single-number thread IDs.
117with_test_prefix "single inferior" {
118 info_threads "" "1"
119
120 gdb_test "thread" "Current thread is 1 .*"
121}
122
123# "info threads" while there are multiple inferiors should show
124# qualified thread IDs.
125with_test_prefix "two inferiors" {
126 # Add another inferior.
127 gdb_test "add-inferior" "Added inferior 2.*" "add empty inferior 2"
128
129 # Now that we've added another inferior, thread IDs now show the
130 # inferior number.
131 info_threads "" "1.1"
132
133 gdb_test "thread" "Current thread is 1\.1 .*"
134
135 gdb_test "inferior 2" "Switching to inferior 2 .*" "switch to inferior 2"
136 gdb_test "file ${binfile}" ".*" "load file in inferior 2"
137
138 runto_main
139
140 # Now that we've added another inferior, thread IDs now show the
141 # inferior number.
142 info_threads "" "1.1 2.1" \
143 "info threads show inferior numbers"
144
145 gdb_test "thread" "Current thread is 2\.1 .*" \
146 "switch to thread using extended thread ID"
147
148 gdb_breakpoint "thread_function1"
149
150 gdb_continue_to_breakpoint "once"
151 gdb_test "inferior 1" "Switching to inferior 1 .*"
152 gdb_continue_to_breakpoint "twice"
153
154 info_threads "" "1.1 1.2 2.1 2.2" \
155 "info threads again"
156
c84f6bbf
PA
157 # Same, but show the global ID.
158 gdb_test "info threads -gid" \
159 [multi_line \
160 " 1\.1 +1 +.*" \
161 "\\* 1\.2 +4 +.* thread_function1 .* at .*$srcfile:.*" \
162 " 2\.1 +2 +.*" \
163 " 2\.2 +3 +.* thread_function1 .* at .*$srcfile:.*"]
164
663f6d42 165 # Confirm the convenience variables show the expected numbers.
5d5658a1 166 gdb_test "p \$_thread == 2" " = 1"
663f6d42 167 gdb_test "p \$_gthread == 4" " = 1"
5d5658a1
PA
168
169 # Without an explicit inferior component, GDB defaults to the
170 # current inferior. Make sure we don't refer to a thread by
171 # global ID by mistake.
172 gdb_test "thread 4" "Unknown thread 1.4\\."
173
174 # Test thread ID list parsing. Test qualified and unqualified
175 # IDs; qualified and unqualified ranges; invalid IDs and invalid
176 # ranges.
177
178 # First spawn a couple more threads so ranges includes more than
179 # two threads.
180 with_test_prefix "more threads" {
181 gdb_breakpoint "thread_function2"
182
183 gdb_test "inferior 2" "Switching to inferior 2 .*"
184 gdb_continue_to_breakpoint "once"
185
186 gdb_test "inferior 1" "Switching to inferior 1 .*"
187 gdb_continue_to_breakpoint "twice"
188 }
189
3f5b7598
PA
190 thr_apply_info_thr "1" \
191 "1.1"
192
193 thr_apply_info_thr "1.1" \
194 "1.1"
195
5d5658a1
PA
196 thr_apply_info_thr "1 2 3" \
197 "1.1 1.2 1.3"
198
199 # Same, but with qualified thread IDs.
200 thr_apply_info_thr "1.1 1.2 1.3 2.1 2.2" \
201 "1.1 1.2 1.3 2.1 2.2"
202
203 # Test a thread number range.
204 thr_apply_info_thr "1-3" \
205 "1.1 1.2 1.3"
206
207 # Same, but using a qualified range.
208 thr_apply_info_thr "1.1-3" \
209 "1.1 1.2 1.3"
210
211 # A mix of qualified and unqualified thread IDs/ranges.
212 thr_apply_info_thr "1.1 2-3" \
213 "1.1 1.2 1.3"
214
215 thr_apply_info_thr "1 1.2-3" \
216 "1.1 1.2 1.3"
217
218 # Likewise, but mix inferiors too.
219 thr_apply_info_thr "2.1 2-3" \
220 "1.2 1.3 2.1" \
221 "2.1 1.2 1.3"
222
223 # Multiple ranges with mixed explicit inferiors.
224 thr_apply_info_thr "1.1-2 2.2-3" \
225 "1.1 1.2 2.2 2.3"
226
3f5b7598
PA
227 # Now test using GDB convenience variables.
228
229 gdb_test "p \$inf = 1" " = 1"
230 gdb_test "p \$thr_start = 2" " = 2"
231 gdb_test "p \$thr_end = 3" " = 3"
232
233 # Convenience variable for the inferior number, only.
234 thr_apply_info_thr "\$inf.2" \
235 "1.2"
236 thr_apply_info_thr "\$inf.2-3" \
237 "1.2 1.3"
238
239 # Convenience variables for thread numbers as well.
240 foreach prefix {"" "1." "\$inf."} {
241 thr_apply_info_thr "${prefix}\$thr_start" \
242 "1.2"
243 thr_apply_info_thr "${prefix}\$thr_start-\$thr_end" \
244 "1.2 1.3"
245 thr_apply_info_thr "${prefix}2-\$thr_end" \
246 "1.2 1.3"
247 thr_apply_info_thr "${prefix}\$thr_start-3" \
248 "1.2 1.3"
249
250 # Undefined convenience variable.
251 set prefix_re [string_to_regexp $prefix]
252 thr_apply_info_thr_error "${prefix}\$conv123" \
253 [multi_line \
254 "Convenience variable must have integer value\." \
255 "Invalid thread ID: ${prefix_re}\\\$conv123"]
256 }
257
258 # Convenience variables pointing at an inexisting thread and/or
259 # inferior.
260 gdb_test "p \$inf = 30" " = 30"
261 gdb_test "p \$thr = 20" " = 20"
262 # Try both the convenience variable and the literal number.
263 foreach thr {"\$thr" "20" "1.20" "\$inf.1" "30.1" } {
264 set expected [string_to_regexp $thr]
265 gdb_test "info threads $thr" "No threads match '${expected}'."
266 # "info threads" works like a filter. If there's any other
267 # valid thread in the list, there's no error.
268 info_threads "$thr 1.1" "1.1"
269 info_threads "1.1 $thr" "1.1"
270 }
271
272 gdb_test "thread apply \$thr p 1234" \
273 "warning: Unknown thread 1.20" \
274 "thread apply \$thr"
275
276 gdb_test "thread apply \$inf.1 p 1234" \
277 "warning: Unknown thread 30.1" \
278 "thread apply \$inf.1"
279
5d5658a1
PA
280 # Now test a set of invalid thread IDs/ranges.
281
282 thr_apply_info_thr_invalid "1." \
283 "1."
284
285 thr_apply_info_thr_invalid "1-3 1." \
286 "1."
287
288 thr_apply_info_thr_invalid "1.1.1" \
289 "1.1.1"
290
291 thr_apply_info_thr_invalid "2 1.1.1" \
292 "1.1.1"
293
294 thr_apply_info_thr_invalid "1.1.1 2" \
295 "1.1.1 2"
296
297 thr_apply_info_thr_invalid "1-2.1" \
298 "1-2.1"
299
3f5b7598
PA
300 gdb_test "p \$zero = 0" " = 0"
301 gdb_test "p \$one = 1" " = 1"
302 gdb_test "p \$minus_one = -11" " = -11"
303 foreach prefix {"" "1." "$one."} {
304 set prefix_re [string_to_regexp $prefix]
305
306 thr_apply_info_thr_invalid "${prefix}foo"
307 thr_apply_info_thr_invalid "${prefix}1foo"
308 thr_apply_info_thr_invalid "${prefix}foo1"
309
310 thr_apply_info_thr_error "${prefix}1-0" "inverted range"
311 thr_apply_info_thr_error "${prefix}1-\$zero" "inverted range"
312 thr_apply_info_thr_error "${prefix}\$one-0" "inverted range"
313 thr_apply_info_thr_error "${prefix}\$one-\$zero" "inverted range"
314 thr_apply_info_thr_error "${prefix}1-" "inverted range"
315 thr_apply_info_thr_error "${prefix}2-1" "inverted range"
316 thr_apply_info_thr_error "${prefix}2-\$one" "inverted range"
317 thr_apply_info_thr_error "${prefix}-1" "negative value"
318 thr_apply_info_thr_error "${prefix}-\$one" "negative value"
319 thr_apply_info_thr_error "${prefix}\$minus_one" \
320 "negative value: ${prefix_re}\\\$minus_one"
321 }
5d5658a1 322
3f5b7598
PA
323 # Check that a valid thread ID list with a missing command errors
324 # out.
325 with_test_prefix "missing command" {
326 set output "Please specify a command following the thread ID list"
327 gdb_test "thread apply 1" $output
328 gdb_test "thread apply 1.1" $output
329 gdb_test "thread apply 1.1 1.2" $output
330 gdb_test "thread apply 1-2" $output
331 gdb_test "thread apply 1.1-2" $output
332 gdb_test "thread apply $thr" $output
333 }
5d5658a1
PA
334
335 # Check that we do parse the inferior number and don't confuse it.
336 gdb_test "info threads 3.1" \
337 "No threads match '3.1'\."
338}
339
340if { ![skip_python_tests] } {
341 with_test_prefix "python" {
22a02324
PA
342 # Check that InferiorThread.num and InferiorThread.global_num
343 # return the expected numbers.
5d5658a1
PA
344 gdb_py_test_silent_cmd "python t0 = gdb.selected_thread ()" \
345 "test gdb.selected_thread" 1
346 gdb_test "python print ('result = %s' % t0.num)" " = 3" \
347 "test InferiorThread.num"
22a02324
PA
348 gdb_test "python print ('result = %s' % t0.global_num)" " = 6" \
349 "test InferiorThread.global_num"
350
351 # Breakpoint.thread expects global IDs. Confirm that that
352 # works as expected.
353 delete_breakpoints
354 gdb_breakpoint "thread_function1"
355
356 gdb_py_test_silent_cmd "python bp = gdb.breakpoints()\[0\]" \
357 "get python breakpoint" 0
358 gdb_test "python bp.thread = 6" "thread = 6" \
359 "make breakpoint thread-specific with python"
360 # Check that the inferior-qualified ID is correct.
361 gdb_test "info breakpoint" \
362 "stop only in thread 1.3\r\n.*" \
363 "thread specific breakpoint right thread"
5d5658a1
PA
364 }
365}
366
367# Remove the second inferior and confirm that GDB goes back to showing
368# single-number thread IDs.
369with_test_prefix "back to one inferior" {
370 gdb_test "kill inferior 2" "" "kill inferior 2" "Kill the program being debugged.*" "y"
371 gdb_test "thread 1.1" "Switching to thread 1\.1 .*"
372 gdb_test "remove-inferior 2" ".*" "remove inferior 2"
373
374 # "info threads" while there's only inferior 1 should show
375 # single-number thread IDs.
376 info_threads "" "1 2 3"
377
378 gdb_test "thread" "Current thread is 1 .*"
379}
380
381# Add another inferior and remove inferior 1. Since even though
382# there's a single inferior, its number is not 1, GDB should show
383# inferior-qualified thread IDs.
384with_test_prefix "single-inferior but not initial" {
385 # Add another inferior.
386 gdb_test "add-inferior" "Added inferior 3.*" "add empty inferior"
387
388 # Now that we'd added another inferior, thread IDs should show the
389 # inferior number.
390 info_threads "" "1.1 1.2 1.3" \
391 "info threads with multiple inferiors"
392
393 gdb_test "thread" "Current thread is 1\.1 .*"
394
395 gdb_test "inferior 3" "Switching to inferior 3 .*" "switch to inferior 3"
396 gdb_test "file ${binfile}" ".*" "load file in inferior 3"
397
398 runto_main
399
400 gdb_test "remove-inferior 1" ".*" "remove inferior 1"
401
402 # Even though we have a single inferior, its number is > 1, so
403 # thread IDs should include the inferior number.
404 info_threads "" "3.1" \
405 "info threads with single inferior"
406
407 gdb_test "thread" "Current thread is 3\.1 .*" "thread again"
408}