Implement "info threads -gid"
[external/binutils.git] / gdb / testsuite / gdb.multi / tids.exp
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
18 load_lib gdb-python.exp
19
20 standard_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.
25 if [target_info exists use_gdb_stub] {
26     untested ${testfile}.exp
27     return
28 }
29
30 if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} {pthreads debug}] } {
31     return -1
32 }
33
34 clean_restart ${testfile}
35
36 if { ![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.
42 proc 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.
63 proc 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.
78 proc 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.
89 proc 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.
101 proc 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.
113 with_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.
121 with_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     # Same, but show the global ID.
154     gdb_test "info threads -gid" \
155         [multi_line \
156              "  1\.1 +1 +.*" \
157              "\\* 1\.2 +4 +.* thread_function1 .* at .*$srcfile:.*" \
158              "  2\.1 +2 +.*" \
159              "  2\.2 +3 +.* thread_function1 .* at .*$srcfile:.*"]
160
161     # Confirm the convenience variable show the expected number.
162     gdb_test "p \$_thread == 2" " = 1"
163
164     # Without an explicit inferior component, GDB defaults to the
165     # current inferior.  Make sure we don't refer to a thread by
166     # global ID by mistake.
167     gdb_test "thread 4" "Unknown thread 1.4\\."
168
169     # Test thread ID list parsing.  Test qualified and unqualified
170     # IDs; qualified and unqualified ranges; invalid IDs and invalid
171     # ranges.
172
173     # First spawn a couple more threads so ranges includes more than
174     # two threads.
175     with_test_prefix "more threads" {
176         gdb_breakpoint "thread_function2"
177
178         gdb_test "inferior 2" "Switching to inferior 2 .*"
179         gdb_continue_to_breakpoint "once"
180
181         gdb_test "inferior 1" "Switching to inferior 1 .*"
182         gdb_continue_to_breakpoint "twice"
183     }
184
185     thr_apply_info_thr "1 2 3" \
186         "1.1 1.2 1.3"
187
188     # Same, but with qualified thread IDs.
189     thr_apply_info_thr "1.1 1.2 1.3 2.1 2.2" \
190         "1.1 1.2 1.3 2.1 2.2"
191
192     # Test a thread number range.
193     thr_apply_info_thr "1-3" \
194         "1.1 1.2 1.3"
195
196     # Same, but using a qualified range.
197     thr_apply_info_thr "1.1-3" \
198         "1.1 1.2 1.3"
199
200     # A mix of qualified and unqualified thread IDs/ranges.
201     thr_apply_info_thr "1.1 2-3" \
202         "1.1 1.2 1.3"
203
204     thr_apply_info_thr "1 1.2-3" \
205         "1.1 1.2 1.3"
206
207     # Likewise, but mix inferiors too.
208     thr_apply_info_thr "2.1 2-3" \
209         "1.2 1.3 2.1" \
210         "2.1 1.2 1.3"
211
212     # Multiple ranges with mixed explicit inferiors.
213     thr_apply_info_thr "1.1-2 2.2-3" \
214         "1.1 1.2 2.2 2.3"
215
216     # Now test a set of invalid thread IDs/ranges.
217
218     thr_apply_info_thr_invalid "1." \
219         "1."
220
221     thr_apply_info_thr_invalid "1-3 1." \
222         "1."
223
224     thr_apply_info_thr_invalid "1.1.1" \
225         "1.1.1"
226
227     thr_apply_info_thr_invalid "2 1.1.1" \
228         "1.1.1"
229
230     thr_apply_info_thr_invalid "1.1.1 2" \
231         "1.1.1 2"
232
233     thr_apply_info_thr_invalid "1-2.1" \
234         "1-2.1"
235
236     thr_apply_info_thr_error "1-0" "inverted range"
237     thr_apply_info_thr_error "1.1-0" "inverted range"
238
239     thr_apply_info_thr_error "1-" "inverted range"
240     thr_apply_info_thr_error "1.1-" "inverted range"
241
242     thr_apply_info_thr_error "2-1" "inverted range"
243     thr_apply_info_thr_error "1.2-1" "inverted range"
244
245     thr_apply_info_thr_error "-1" "negative value"
246     thr_apply_info_thr_error "1.-1" "negative value"
247
248     # Check that we do parse the inferior number and don't confuse it.
249     gdb_test "info threads 3.1" \
250         "No threads match '3.1'\."
251 }
252
253 if { ![skip_python_tests] } {
254     with_test_prefix "python" {
255         # Check that InferiorThread.num and InferiorThread.global_num
256         # return the expected numbers.
257         gdb_py_test_silent_cmd "python t0 = gdb.selected_thread ()" \
258             "test gdb.selected_thread" 1
259         gdb_test "python print ('result = %s' % t0.num)" " = 3" \
260             "test InferiorThread.num"
261         gdb_test "python print ('result = %s' % t0.global_num)" " = 6" \
262             "test InferiorThread.global_num"
263
264         # Breakpoint.thread expects global IDs.  Confirm that that
265         # works as expected.
266         delete_breakpoints
267         gdb_breakpoint "thread_function1"
268
269         gdb_py_test_silent_cmd "python bp = gdb.breakpoints()\[0\]" \
270             "get python breakpoint" 0
271         gdb_test "python bp.thread = 6" "thread = 6" \
272             "make breakpoint thread-specific with python"
273         # Check that the inferior-qualified ID is correct.
274         gdb_test "info breakpoint" \
275             "stop only in thread 1.3\r\n.*" \
276             "thread specific breakpoint right thread"
277     }
278 }
279
280 # Remove the second inferior and confirm that GDB goes back to showing
281 # single-number thread IDs.
282 with_test_prefix "back to one inferior" {
283     gdb_test "kill inferior 2" "" "kill inferior 2" "Kill the program being debugged.*" "y"
284     gdb_test "thread 1.1" "Switching to thread 1\.1 .*"
285     gdb_test "remove-inferior 2" ".*" "remove inferior 2"
286
287     # "info threads" while there's only inferior 1 should show
288     # single-number thread IDs.
289     info_threads "" "1 2 3"
290
291     gdb_test "thread" "Current thread is 1 .*"
292 }
293
294 # Add another inferior and remove inferior 1.  Since even though
295 # there's a single inferior, its number is not 1, GDB should show
296 # inferior-qualified thread IDs.
297 with_test_prefix "single-inferior but not initial" {
298     # Add another inferior.
299     gdb_test "add-inferior" "Added inferior 3.*" "add empty inferior"
300
301     # Now that we'd added another inferior, thread IDs should show the
302     # inferior number.
303     info_threads "" "1.1 1.2 1.3" \
304         "info threads with multiple inferiors"
305
306     gdb_test "thread" "Current thread is 1\.1 .*"
307
308     gdb_test "inferior 3" "Switching to inferior 3 .*" "switch to inferior 3"
309     gdb_test "file ${binfile}" ".*" "load file in inferior 3"
310
311     runto_main
312
313     gdb_test "remove-inferior 1" ".*" "remove inferior 1"
314
315     # Even though we have a single inferior, its number is > 1, so
316     # thread IDs should include the inferior number.
317     info_threads "" "3.1" \
318         "info threads with single inferior"
319
320     gdb_test "thread" "Current thread is 3\.1 .*" "thread again"
321 }