]> Git Repo - binutils.git/blame - gdb/testsuite/gdb.multi/tids.exp
Per-inferior/Inferior-qualified thread IDs
[binutils.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
93 gdb_test "thread apply $tid_list p 1234" \
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".
100# EXPECTED is a literal string, not a regexp.
101proc thr_apply_info_thr_invalid {tid_list expected} {
102 set expected [string_to_regexp $expected]
103 gdb_test "info threads $tid_list" \
104 "Invalid thread ID: $expected"
105
106 gdb_test "thread apply $tid_list p 1234" \
107 "Invalid thread ID: $expected p 1234" \
108 "thread apply $tid_list"
109}
110
111# "info threads" while there's only inferior 1 should show
112# single-number thread IDs.
113with_test_prefix "single inferior" {
114 info_threads "" "1"
115
116 gdb_test "thread" "Current thread is 1 .*"
117}
118
119# "info threads" while there are multiple inferiors should show
120# qualified thread IDs.
121with_test_prefix "two inferiors" {
122 # Add another inferior.
123 gdb_test "add-inferior" "Added inferior 2.*" "add empty inferior 2"
124
125 # Now that we've added another inferior, thread IDs now show the
126 # inferior number.
127 info_threads "" "1.1"
128
129 gdb_test "thread" "Current thread is 1\.1 .*"
130
131 gdb_test "inferior 2" "Switching to inferior 2 .*" "switch to inferior 2"
132 gdb_test "file ${binfile}" ".*" "load file in inferior 2"
133
134 runto_main
135
136 # Now that we've added another inferior, thread IDs now show the
137 # inferior number.
138 info_threads "" "1.1 2.1" \
139 "info threads show inferior numbers"
140
141 gdb_test "thread" "Current thread is 2\.1 .*" \
142 "switch to thread using extended thread ID"
143
144 gdb_breakpoint "thread_function1"
145
146 gdb_continue_to_breakpoint "once"
147 gdb_test "inferior 1" "Switching to inferior 1 .*"
148 gdb_continue_to_breakpoint "twice"
149
150 info_threads "" "1.1 1.2 2.1 2.2" \
151 "info threads again"
152
153 # Confirm the convenience variable show the expected number.
154 gdb_test "p \$_thread == 2" " = 1"
155
156 # Without an explicit inferior component, GDB defaults to the
157 # current inferior. Make sure we don't refer to a thread by
158 # global ID by mistake.
159 gdb_test "thread 4" "Unknown thread 1.4\\."
160
161 # Test thread ID list parsing. Test qualified and unqualified
162 # IDs; qualified and unqualified ranges; invalid IDs and invalid
163 # ranges.
164
165 # First spawn a couple more threads so ranges includes more than
166 # two threads.
167 with_test_prefix "more threads" {
168 gdb_breakpoint "thread_function2"
169
170 gdb_test "inferior 2" "Switching to inferior 2 .*"
171 gdb_continue_to_breakpoint "once"
172
173 gdb_test "inferior 1" "Switching to inferior 1 .*"
174 gdb_continue_to_breakpoint "twice"
175 }
176
177 thr_apply_info_thr "1 2 3" \
178 "1.1 1.2 1.3"
179
180 # Same, but with qualified thread IDs.
181 thr_apply_info_thr "1.1 1.2 1.3 2.1 2.2" \
182 "1.1 1.2 1.3 2.1 2.2"
183
184 # Test a thread number range.
185 thr_apply_info_thr "1-3" \
186 "1.1 1.2 1.3"
187
188 # Same, but using a qualified range.
189 thr_apply_info_thr "1.1-3" \
190 "1.1 1.2 1.3"
191
192 # A mix of qualified and unqualified thread IDs/ranges.
193 thr_apply_info_thr "1.1 2-3" \
194 "1.1 1.2 1.3"
195
196 thr_apply_info_thr "1 1.2-3" \
197 "1.1 1.2 1.3"
198
199 # Likewise, but mix inferiors too.
200 thr_apply_info_thr "2.1 2-3" \
201 "1.2 1.3 2.1" \
202 "2.1 1.2 1.3"
203
204 # Multiple ranges with mixed explicit inferiors.
205 thr_apply_info_thr "1.1-2 2.2-3" \
206 "1.1 1.2 2.2 2.3"
207
208 # Now test a set of invalid thread IDs/ranges.
209
210 thr_apply_info_thr_invalid "1." \
211 "1."
212
213 thr_apply_info_thr_invalid "1-3 1." \
214 "1."
215
216 thr_apply_info_thr_invalid "1.1.1" \
217 "1.1.1"
218
219 thr_apply_info_thr_invalid "2 1.1.1" \
220 "1.1.1"
221
222 thr_apply_info_thr_invalid "1.1.1 2" \
223 "1.1.1 2"
224
225 thr_apply_info_thr_invalid "1-2.1" \
226 "1-2.1"
227
228 thr_apply_info_thr_error "1-0" "inverted range"
229 thr_apply_info_thr_error "1.1-0" "inverted range"
230
231 thr_apply_info_thr_error "1-" "inverted range"
232 thr_apply_info_thr_error "1.1-" "inverted range"
233
234 thr_apply_info_thr_error "2-1" "inverted range"
235 thr_apply_info_thr_error "1.2-1" "inverted range"
236
237 thr_apply_info_thr_error "-1" "negative value"
238 thr_apply_info_thr_error "1.-1" "negative value"
239
240 # Check that we do parse the inferior number and don't confuse it.
241 gdb_test "info threads 3.1" \
242 "No threads match '3.1'\."
243}
244
245if { ![skip_python_tests] } {
246 with_test_prefix "python" {
247 # Check that InferiorThread.num returns the expected number.
248 gdb_py_test_silent_cmd "python t0 = gdb.selected_thread ()" \
249 "test gdb.selected_thread" 1
250 gdb_test "python print ('result = %s' % t0.num)" " = 3" \
251 "test InferiorThread.num"
252 }
253}
254
255# Remove the second inferior and confirm that GDB goes back to showing
256# single-number thread IDs.
257with_test_prefix "back to one inferior" {
258 gdb_test "kill inferior 2" "" "kill inferior 2" "Kill the program being debugged.*" "y"
259 gdb_test "thread 1.1" "Switching to thread 1\.1 .*"
260 gdb_test "remove-inferior 2" ".*" "remove inferior 2"
261
262 # "info threads" while there's only inferior 1 should show
263 # single-number thread IDs.
264 info_threads "" "1 2 3"
265
266 gdb_test "thread" "Current thread is 1 .*"
267}
268
269# Add another inferior and remove inferior 1. Since even though
270# there's a single inferior, its number is not 1, GDB should show
271# inferior-qualified thread IDs.
272with_test_prefix "single-inferior but not initial" {
273 # Add another inferior.
274 gdb_test "add-inferior" "Added inferior 3.*" "add empty inferior"
275
276 # Now that we'd added another inferior, thread IDs should show the
277 # inferior number.
278 info_threads "" "1.1 1.2 1.3" \
279 "info threads with multiple inferiors"
280
281 gdb_test "thread" "Current thread is 1\.1 .*"
282
283 gdb_test "inferior 3" "Switching to inferior 3 .*" "switch to inferior 3"
284 gdb_test "file ${binfile}" ".*" "load file in inferior 3"
285
286 runto_main
287
288 gdb_test "remove-inferior 1" ".*" "remove inferior 1"
289
290 # Even though we have a single inferior, its number is > 1, so
291 # thread IDs should include the inferior number.
292 info_threads "" "3.1" \
293 "info threads with single inferior"
294
295 gdb_test "thread" "Current thread is 3\.1 .*" "thread again"
296}
This page took 0.056447 seconds and 4 git commands to generate.