user-selected-context-sync.exp revision 1.1.1.6 1 1.1.1.6 christos # Copyright 2016-2024 Free Software Foundation, Inc.
2 1.1 christos
3 1.1 christos # This program is free software; you can redistribute it and/or modify
4 1.1 christos # it under the terms of the GNU General Public License as published by
5 1.1 christos # the Free Software Foundation; either version 3 of the License, or
6 1.1 christos # (at your option) any later version.
7 1.1 christos #
8 1.1 christos # This program is distributed in the hope that it will be useful,
9 1.1 christos # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 1.1 christos # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 1.1 christos # GNU General Public License for more details.
12 1.1 christos #
13 1.1 christos # You should have received a copy of the GNU General Public License
14 1.1 christos # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 1.1 christos
16 1.1 christos # This test checks that the "thread", "select-frame", "frame" and "inferior"
17 1.1 christos # CLI commands, as well as the "-thread-select" and "-stack-select-frame" MI
18 1.1 christos # commands send the appropriate user-selection-change events to all UIs.
19 1.1 christos #
20 1.1 christos # This test considers the case where console and MI are two different UIs,
21 1.1 christos # and MI is created with the new-ui command.
22 1.1 christos #
23 1.1 christos # It also considers the case where the console commands are sent directly in
24 1.1 christos # the MI channel as described in PR 20487.
25 1.1 christos #
26 1.1 christos # It does so by starting 2 inferiors with 3 threads each.
27 1.1 christos # - Thread 1 of each inferior is the main thread, starting the others.
28 1.1 christos # - Thread 2 of each inferior is stopped at /* thread loop line */.
29 1.1 christos # - Thread 3 of each inferior is either stopped at /* thread loop line */, if we
30 1.1 christos # are using all-stop, or running, if we are using non-stop.
31 1.1 christos
32 1.1.1.4 christos # Do not run if gdb debug is enabled as it doesn't work for separate-mi-tty.
33 1.1.1.6 christos require !gdb_debug_enabled
34 1.1.1.4 christos
35 1.1 christos load_lib mi-support.exp
36 1.1 christos
37 1.1 christos standard_testfile
38 1.1 christos
39 1.1 christos # Multiple inferiors are needed, therefore only native gdb and extended
40 1.1 christos # gdbserver modes are supported.
41 1.1.1.6 christos require !use_gdb_stub
42 1.1 christos
43 1.1 christos set compile_options "debug pthreads"
44 1.1 christos if {[build_executable $testfile.exp $testfile ${srcfile} ${compile_options}] == -1} {
45 1.1.1.2 christos untested "failed to compile"
46 1.1 christos return -1
47 1.1 christos }
48 1.1 christos
49 1.1 christos set main_break_line [gdb_get_line_number "main break line"]
50 1.1 christos set thread_loop_line [gdb_get_line_number "thread loop line"]
51 1.1 christos set thread_caller_line [gdb_get_line_number "thread caller line"]
52 1.1 christos
53 1.1 christos # Return whether we expect thread THREAD to be running in mode MODE.
54 1.1 christos #
55 1.1 christos # MODE can be either "all-stop" or "non-stop".
56 1.1 christos # THREAD can be either a CLI thread id (e.g. 2.3) or an MI thread id (e.g. 6).
57 1.1 christos
58 1.1 christos proc thread_is_running { mode thread } {
59 1.1 christos if { $mode != "non-stop" } {
60 1.1 christos return 0
61 1.1 christos }
62 1.1 christos
63 1.1 christos return [expr {
64 1.1 christos $thread == 1.3
65 1.1 christos || $thread == 2.3
66 1.1 christos || $thread == 3
67 1.1 christos || $thread == 6
68 1.1 christos }]
69 1.1 christos }
70 1.1 christos
71 1.1 christos # Make a regular expression to match the various inferior/thread/frame selection
72 1.1 christos # events for CLI.
73 1.1 christos #
74 1.1 christos # MODE can be either "all-stop" or "non-stop", indicating which one is currently
75 1.1 christos # in use.
76 1.1 christos # INF is the inferior number we are expecting GDB to switch to, or -1 if we are
77 1.1 christos # not expecting GDB to announce an inferior switch.
78 1.1 christos # THREAD is the thread number we are expecting GDB to switch to, or -1 if we are
79 1.1 christos # not expecting GDB to announce a thread switch.
80 1.1 christos # FRAME is the frame number we are expecting GDB to switch to, or -1 if we are
81 1.1 christos # not expecting GDB to announce a frame switch. See the FRAME_RE variable for
82 1.1 christos # details.
83 1.1 christos
84 1.1 christos proc make_cli_re { mode inf thread frame } {
85 1.1 christos global srcfile
86 1.1 christos global thread_caller_line
87 1.1 christos global thread_loop_line
88 1.1 christos global main_break_line
89 1.1 christos global decimal
90 1.1 christos
91 1.1 christos set any "\[^\r\n\]*"
92 1.1 christos
93 1.1 christos set cli_re ""
94 1.1 christos
95 1.1 christos set inf_re "\\\[Switching to inferior $inf${any}\\\]"
96 1.1 christos set all_stop_thread_re "\\\[Switching to thread [string_to_regexp $thread]${any}\\\]"
97 1.1 christos
98 1.1 christos set frame_re(0) "#0${any}child_sub_function$any$srcfile:$thread_loop_line\r\n${any}thread loop line \\\*/"
99 1.1 christos set frame_re(1) "#1${any}child_function \\\(args=0x0\\\) at ${any}$srcfile:$thread_caller_line\r\n$thread_caller_line${any}/\\\* thread caller line \\\*/"
100 1.1 christos
101 1.1 christos # Special frame for main thread.
102 1.1 christos set frame_re(2) "#0${any}\r\n${main_break_line}${any}"
103 1.1 christos
104 1.1 christos if { $inf != -1 } {
105 1.1 christos append cli_re $inf_re
106 1.1 christos }
107 1.1 christos
108 1.1 christos if { $thread != -1 } {
109 1.1 christos if { $inf != -1 } {
110 1.1 christos append cli_re "\r\n"
111 1.1 christos }
112 1.1 christos set thread_re $all_stop_thread_re
113 1.1 christos
114 1.1 christos if [thread_is_running $mode $thread] {
115 1.1 christos set thread_re "$thread_re\\\(running\\\)"
116 1.1 christos }
117 1.1 christos
118 1.1 christos append cli_re $thread_re
119 1.1 christos }
120 1.1 christos
121 1.1 christos if { $frame != -1 } {
122 1.1 christos if { $thread != -1 } {
123 1.1 christos append cli_re "\r\n"
124 1.1 christos }
125 1.1 christos append cli_re $frame_re($frame)
126 1.1 christos }
127 1.1 christos
128 1.1 christos return $cli_re
129 1.1 christos }
130 1.1 christos
131 1.1 christos # Make a regular expression to match the various inferior/thread/frame selection
132 1.1 christos # events for MI.
133 1.1 christos #
134 1.1 christos # MODE can be either "all-stop" or "non-stop", indicating which one is currently
135 1.1 christos # in use.
136 1.1 christos # THREAD is the thread number we are expecting GDB to switch to, or -1 if we are
137 1.1 christos # not expecting GDB to announce a thread switch.
138 1.1 christos # If EVENT is 1, build a regex for an "=thread-selected" async event.
139 1.1 christos # Otherwise, build a regex for a response to a command.
140 1.1 christos # FRAME is the frame number we are expecting GDB to switch to, or -1 if we are
141 1.1 christos # not expecting GDB to announce a frame switch. See the FRAME_RE variable for
142 1.1 christos # details.
143 1.1 christos
144 1.1 christos proc make_mi_re { mode thread frame type } {
145 1.1 christos global srcfile
146 1.1 christos global hex
147 1.1 christos global decimal
148 1.1 christos global thread_loop_line
149 1.1 christos global main_break_line
150 1.1 christos global thread_caller_line
151 1.1 christos
152 1.1 christos set any "\[^\r\n\]*"
153 1.1 christos
154 1.1 christos set mi_re ""
155 1.1 christos
156 1.1 christos set thread_event_re "=thread-selected,id=\"$thread\""
157 1.1 christos set thread_answer_re "\\^done,new-thread-id=\"$thread\""
158 1.1 christos
159 1.1.1.3 christos set frame_re(0) ",frame=\{level=\"0\",addr=\"$hex\",func=\"child_sub_function\",args=\\\[\\\],file=\"${any}${srcfile}\",fullname=\"${any}${srcfile}\",line=\"$thread_loop_line\",arch=\"$any\"\}"
160 1.1.1.3 christos set frame_re(1) ",frame=\{level=\"1\",addr=\"$hex\",func=\"child_function\",args=\\\[\{name=\"args\",value=\"0x0\"\}\\\],file=\"${any}${srcfile}\",fullname=\"${any}${srcfile}\",line=\"$thread_caller_line\",arch=\"$any\"\}"
161 1.1 christos
162 1.1 christos # Special frame for main thread.
163 1.1.1.3 christos set frame_re(2) ",frame=\{level=\"0\",addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\"${any}${srcfile}\",fullname=\"${any}${srcfile}\",line=\"${main_break_line}\",arch=\"$any\"\}"
164 1.1 christos
165 1.1 christos if { $thread != -1 } {
166 1.1 christos if { $type == "event" } {
167 1.1 christos append mi_re $thread_event_re
168 1.1 christos } elseif { $type == "response" } {
169 1.1 christos append mi_re $thread_answer_re
170 1.1 christos } else {
171 1.1 christos error "Invalid value for EVENT."
172 1.1 christos }
173 1.1 christos }
174 1.1 christos
175 1.1 christos if { $frame != -1 } {
176 1.1 christos append mi_re $frame_re($frame)
177 1.1 christos }
178 1.1 christos
179 1.1 christos if { $type == "event" } {
180 1.1 christos append mi_re "\r\n"
181 1.1 christos }
182 1.1 christos
183 1.1 christos return $mi_re
184 1.1 christos }
185 1.1 christos
186 1.1 christos # Make a regular expression to match the various inferior/thread/frame selection
187 1.1 christos # events when issuing CLI commands inside MI.
188 1.1 christos #
189 1.1 christos # COMMAND is the CLI command that was sent to GDB, which will be output in the
190 1.1 christos # console output stream.
191 1.1 christos # CLI_IN_MI_MODE indicates which method of CLI-in-MI command is used. It can be
192 1.1 christos # either "direct" of "interpreter-exec".
193 1.1 christos # MODE can be either "all-stop" or "non-stop", indicating which one is currently
194 1.1 christos # in use.
195 1.1 christos # If EVENT is 1, expect a =thread-select MI event.
196 1.1 christos # INF is the inferior number we are expecting GDB to switch to, or -1 if we are
197 1.1 christos # not expecting GDB to announce an inferior switch.
198 1.1 christos # CLI_THREAD is the thread number as seen in the CLI (inferior-qualified) we are
199 1.1 christos # expecting GDB to switch to, or -1 if we are not expecting GDB to announce a
200 1.1 christos # thread switch.
201 1.1 christos # MI_THREAD is the thread number as seen in the MI (global number) we are
202 1.1 christos # expecting GDB to switch to, or -1 if we are not expecting GDB to announce a
203 1.1 christos # thread switch.
204 1.1 christos # FRAME is the frame number we are expecting GDB to switch to, or -1 if we are
205 1.1 christos # not expecting GDB to announce a frame switch. See the FRAME_RE variable for
206 1.1 christos # details.
207 1.1 christos
208 1.1 christos proc make_cli_in_mi_re { command cli_in_mi_mode mode event inf cli_thread
209 1.1 christos mi_thread frame } {
210 1.1 christos global srcfile
211 1.1 christos global thread_loop_line
212 1.1 christos global main_break_line
213 1.1 christos global thread_caller_line
214 1.1 christos
215 1.1 christos set any "\[^\r\n\]*"
216 1.1 christos
217 1.1 christos set command_re [string_to_regexp $command]
218 1.1 christos set cli_in_mi_re "$command_re\r\n"
219 1.1 christos
220 1.1 christos if { $cli_in_mi_mode == "direct" } {
221 1.1 christos append cli_in_mi_re "&\"$command_re\\\\n\"\r\n"
222 1.1 christos }
223 1.1 christos
224 1.1 christos set frame_re(0) "~\"#0${any}child_sub_function${any}$srcfile:$thread_loop_line\\\\n\"\r\n~\"${thread_loop_line}${any}thread loop line \\\*/\\\\n\"\r\n"
225 1.1 christos set frame_re(1) "~\"#1${any}child_function \\\(args=0x0\\\) at ${any}$srcfile:$thread_caller_line\\\\n\"\r\n~\"$thread_caller_line${any}thread caller line \\\*/\\\\n\"\r\n"
226 1.1 christos
227 1.1 christos # Special frame for main thread.
228 1.1 christos set frame_re(2) "~\"#0${any}main${any}\\\\n\"\r\n~\"${main_break_line}${any}\"\r\n"
229 1.1 christos
230 1.1 christos if { $inf != -1 } {
231 1.1 christos append cli_in_mi_re "~\""
232 1.1 christos append cli_in_mi_re [make_cli_re $mode $inf -1 -1]
233 1.1 christos append cli_in_mi_re "\\\\n\"\r\n"
234 1.1 christos }
235 1.1 christos
236 1.1 christos if { $cli_thread != "-1" } {
237 1.1 christos append cli_in_mi_re "~\""
238 1.1 christos append cli_in_mi_re [make_cli_re $mode -1 $cli_thread -1]
239 1.1 christos append cli_in_mi_re "\\\\n\"\r\n"
240 1.1 christos }
241 1.1 christos
242 1.1 christos if { $frame != -1 } {
243 1.1 christos append cli_in_mi_re $frame_re($frame)
244 1.1 christos }
245 1.1 christos
246 1.1 christos if { $event == 1 } {
247 1.1 christos append cli_in_mi_re [make_mi_re $mode $mi_thread $frame event]
248 1.1 christos }
249 1.1 christos
250 1.1 christos append cli_in_mi_re "\\^done"
251 1.1 christos
252 1.1 christos return $cli_in_mi_re
253 1.1 christos }
254 1.1 christos
255 1.1 christos # Return the current value of the "scheduler-locking" parameter.
256 1.1 christos
257 1.1 christos proc show_scheduler_locking { } {
258 1.1 christos global gdb_prompt
259 1.1 christos global expect_out
260 1.1 christos
261 1.1 christos set any "\[^\r\n\]*"
262 1.1 christos
263 1.1 christos set test "show scheduler-locking"
264 1.1 christos gdb_test_multiple $test $test {
265 1.1 christos -re ".*Mode for locking scheduler during execution is \"(${any})\".\r\n$gdb_prompt " {
266 1.1 christos pass $test
267 1.1 christos return $expect_out(1,string)
268 1.1 christos }
269 1.1 christos }
270 1.1 christos
271 1.1 christos error "Couldn't get current scheduler-locking value."
272 1.1 christos }
273 1.1 christos
274 1.1 christos # Prepare inferior INF so it is in the state we expect (see comment at the top).
275 1.1 christos
276 1.1 christos proc test_continue_to_start { mode inf } {
277 1.1 christos global gdb_spawn_id
278 1.1 christos global mi_spawn_id
279 1.1 christos global gdb_main_spawn_id
280 1.1 christos global srcfile
281 1.1 christos global main_break_line
282 1.1 christos global thread_loop_line
283 1.1 christos global decimal
284 1.1 christos global gdb_prompt
285 1.1 christos
286 1.1 christos set any "\[^\r\n\]*"
287 1.1 christos
288 1.1 christos if { $gdb_spawn_id != $gdb_main_spawn_id } {
289 1.1 christos error "This should not happen."
290 1.1 christos }
291 1.1 christos
292 1.1 christos with_test_prefix "inferior $inf" {
293 1.1 christos with_spawn_id $gdb_main_spawn_id {
294 1.1 christos # Continue to the point where we know for sure the threads are
295 1.1 christos # started.
296 1.1 christos gdb_test "tbreak $srcfile:$main_break_line" \
297 1.1 christos "Temporary breakpoint ${any}" \
298 1.1 christos "set breakpoint in main"
299 1.1 christos
300 1.1 christos gdb_continue_to_breakpoint "main breakpoint"
301 1.1 christos
302 1.1 christos # Consume MI event output.
303 1.1 christos with_spawn_id $mi_spawn_id {
304 1.1.1.5 christos if { $inf == 1 } {
305 1.1.1.5 christos mi_expect_stop "breakpoint-hit" "main" "" "$srcfile" \
306 1.1.1.5 christos "$decimal" {"" "disp=\"del\""} "stop at breakpoint in main"
307 1.1.1.5 christos } else {
308 1.1.1.5 christos mi_expect_stop "breakpoint-hit" "main" "" "$srcfile" \
309 1.1.1.5 christos "$decimal" {"" "disp=\"del\"" "locno=\"[0-9]+\""} "stop at breakpoint in main"
310 1.1.1.5 christos }
311 1.1 christos }
312 1.1 christos
313 1.1 christos if { $mode == "all-stop" } {
314 1.1 christos set previous_schedlock_val [show_scheduler_locking]
315 1.1 christos
316 1.1 christos # Set scheduler-locking on, so that we can control threads
317 1.1 christos # independently.
318 1.1 christos gdb_test_no_output "set scheduler-locking on"
319 1.1 christos
320 1.1 christos # Continue each child thread to the point we want them to be.
321 1.1 christos foreach thread { 2 3 } {
322 1.1 christos gdb_test "thread $inf.$thread" ".*" "select child thread $inf.$thread"
323 1.1 christos
324 1.1 christos gdb_test "tbreak $srcfile:$thread_loop_line" \
325 1.1 christos "Temporary breakpoint ${any}" \
326 1.1 christos "set breakpoint for thread $inf.$thread"
327 1.1 christos
328 1.1 christos gdb_continue_to_breakpoint "continue thread $inf.$thread to infinite loop breakpoint"
329 1.1 christos
330 1.1 christos # Consume MI output.
331 1.1 christos with_spawn_id $mi_spawn_id {
332 1.1.1.5 christos if { $inf == 1} {
333 1.1.1.5 christos mi_expect_stop "breakpoint-hit" "child_sub_function" \
334 1.1.1.5 christos "" "$srcfile" "$decimal" {"" "disp=\"del\""} \
335 1.1.1.5 christos "thread $inf.$thread stops MI"
336 1.1.1.5 christos } else {
337 1.1.1.5 christos mi_expect_stop "breakpoint-hit" "child_sub_function" \
338 1.1.1.5 christos "" "$srcfile" "$decimal" {"" "disp=\"del\"" "locno=\"[0-9]+\""} \
339 1.1.1.5 christos "thread $inf.$thread stops MI"
340 1.1.1.5 christos }
341 1.1 christos }
342 1.1 christos }
343 1.1 christos
344 1.1 christos # Restore scheduler-locking to its original value.
345 1.1 christos gdb_test_no_output "set scheduler-locking $previous_schedlock_val"
346 1.1 christos } else { # $mode == "non-stop"
347 1.1 christos # Put a thread-specific breakpoint for thread 2 of the current
348 1.1 christos # inferior. We don't put a breakpoint for thread 3, since we
349 1.1 christos # want to let it run.
350 1.1 christos set test "set thread-specific breakpoint, thread $inf.2"
351 1.1 christos gdb_test_multiple "tbreak $srcfile:$thread_loop_line thread $inf.2" $test {
352 1.1 christos -re "Temporary breakpoint ${any}\r\n$gdb_prompt " {
353 1.1 christos pass $test
354 1.1 christos }
355 1.1 christos }
356 1.1 christos
357 1.1 christos # Confirm the stop of thread $inf.2.
358 1.1 christos set test "thread $inf.2 stops CLI"
359 1.1 christos gdb_test_multiple "" $test {
360 1.1 christos -re "Thread $inf.2 ${any} hit Temporary breakpoint ${any}\r\n$thread_loop_line${any}\r\n" {
361 1.1 christos pass $test
362 1.1 christos }
363 1.1 christos }
364 1.1 christos
365 1.1 christos # Consume MI output.
366 1.1 christos with_spawn_id $mi_spawn_id {
367 1.1.1.5 christos if { $inf == 1} {
368 1.1.1.5 christos mi_expect_stop "breakpoint-hit" "child_sub_function" \
369 1.1.1.5 christos "" "$srcfile" "$decimal" {"" "disp=\"del\""} \
370 1.1.1.5 christos "thread $inf.2 stops MI"
371 1.1.1.5 christos } else {
372 1.1.1.5 christos mi_expect_stop "breakpoint-hit" "child_sub_function" \
373 1.1.1.5 christos "" "$srcfile" "$decimal" {"" "disp=\"del\"" "locno=\"[0-9]+\""} \
374 1.1.1.5 christos "thread $inf.2 stops MI"
375 1.1.1.5 christos }
376 1.1 christos }
377 1.1 christos }
378 1.1 christos }
379 1.1 christos }
380 1.1 christos }
381 1.1 christos
382 1.1 christos # Prepare the test environment.
383 1.1 christos #
384 1.1 christos # MODE can be either "all-stop" or "non-stop".
385 1.1 christos
386 1.1.1.2 christos proc_with_prefix test_setup { mode } {
387 1.1 christos global srcfile
388 1.1 christos global srcdir
389 1.1 christos global subdir
390 1.1 christos global gdb_main_spawn_id
391 1.1 christos global mi_spawn_id
392 1.1 christos global decimal
393 1.1 christos global binfile
394 1.1 christos global GDBFLAGS
395 1.1 christos global async
396 1.1 christos
397 1.1 christos set any "\[^\r\n\]*"
398 1.1 christos
399 1.1 christos save_vars { GDBFLAGS } {
400 1.1 christos if { $mode == "non-stop" } {
401 1.1 christos set GDBFLAGS [concat $GDBFLAGS " -ex \"set non-stop 1\""]
402 1.1 christos }
403 1.1 christos
404 1.1.1.6 christos if { [mi_clean_restart $binfile "separate-mi-tty"] != 0 } {
405 1.1.1.5 christos return -1
406 1.1 christos }
407 1.1 christos }
408 1.1 christos
409 1.1.1.5 christos if { [mi_runto_main] < 0 } {
410 1.1.1.5 christos return -1
411 1.1 christos }
412 1.1 christos
413 1.1 christos # When using mi_expect_stop, we don't expect a prompt after the *stopped
414 1.1 christos # event, since the blocking commands are done from the CLI. Setting async
415 1.1 christos # to 1 makes it not expect the prompt.
416 1.1 christos set async 1
417 1.1 christos
418 1.1 christos with_spawn_id $gdb_main_spawn_id {
419 1.1 christos # Add the second inferior now. While this is not mandatory, it allows
420 1.1 christos # us to assume that per-inferior thread numbering will be used,
421 1.1 christos # simplifying test_continue_to_start a bit (Thread 1.2 and not Thread 2).
422 1.1.1.4 christos gdb_test "add-inferior" "Added inferior 2 on connection .*" "add inferior 2"
423 1.1 christos
424 1.1 christos # Prepare the first inferior for the test.
425 1.1 christos test_continue_to_start $mode 1
426 1.1 christos
427 1.1 christos # Switch to and start the second inferior.
428 1.1 christos gdb_test "inferior 2" "\\\[Switching to inferior 2${any}\\\]" "switch to inferior 2"
429 1.1 christos gdb_load ${binfile}
430 1.1 christos
431 1.1 christos # Doing "start" on the CLI generates a ton of MI output. At some point,
432 1.1 christos # if we don't consume/match it, the buffer between GDB's MI channel and
433 1.1 christos # Expect will get full, GDB will block on a write system call and we'll
434 1.1 christos # deadlock, waiting for CLI output that will never arrive. And then
435 1.1 christos # we're sad. So instead of using gdb_test and expect CLI output, send
436 1.1 christos # the start command first, then consume MI output, and finally consume
437 1.1 christos # CLI output.
438 1.1 christos send_gdb "start\n"
439 1.1 christos
440 1.1 christos with_spawn_id $mi_spawn_id {
441 1.1 christos mi_expect_stop "breakpoint-hit" "main" "" "$srcfile" "$decimal" \
442 1.1.1.5 christos {"" "disp=\"del\"" "locno=\"[0-9]+\""} "main stop"
443 1.1 christos }
444 1.1 christos
445 1.1 christos # Consume CLI output.
446 1.1 christos gdb_test "" "Temporary breakpoint.*Starting program.*"
447 1.1 christos
448 1.1 christos # Prepare the second inferior for the test.
449 1.1 christos test_continue_to_start $mode 2
450 1.1 christos }
451 1.1.1.5 christos
452 1.1.1.5 christos return 0
453 1.1 christos }
454 1.1 christos
455 1.1 christos # Reset the selection to frame #0 of thread THREAD.
456 1.1 christos
457 1.1 christos proc reset_selection { thread } {
458 1.1 christos global gdb_main_spawn_id
459 1.1 christos
460 1.1 christos set any "\[^\r\n\]*"
461 1.1 christos
462 1.1 christos with_spawn_id $gdb_main_spawn_id {
463 1.1 christos gdb_test "thread $thread" \
464 1.1 christos "\\\[Switching to thread $thread ${any}\\\].*" \
465 1.1 christos "reset selection to thread $thread"
466 1.1 christos gdb_test "frame 0" ".*" "reset selection to frame 0"
467 1.1 christos }
468 1.1 christos }
469 1.1 christos
470 1.1 christos # Flush Expect's internal buffers for both CLI and MI.
471 1.1 christos #
472 1.1 christos # The idea here is to send a command, and to consume all the characters that we
473 1.1 christos # expect that command to output, including the following prompt. Using gdb_test
474 1.1 christos # and mi_gdb_test should do that.
475 1.1 christos
476 1.1 christos proc flush_buffers { } {
477 1.1 christos global gdb_main_spawn_id mi_spawn_id
478 1.1 christos
479 1.1 christos with_spawn_id $gdb_main_spawn_id {
480 1.1 christos gdb_test "print 444" "= 444" "flush CLI"
481 1.1 christos }
482 1.1 christos
483 1.1 christos with_spawn_id $mi_spawn_id {
484 1.1 christos mi_gdb_test "555-data-evaluate-expression 666" ".*done,value=\"666\"" "flush MI"
485 1.1 christos }
486 1.1 christos }
487 1.1 christos
488 1.1 christos # Run a command on the current spawn id, to confirm that no output is pending
489 1.1 christos # in Expect's internal buffer. This is used to ensure that nothing was output
490 1.1 christos # on the spawn id since the call to gdb_test/mi_gdb_test/flush_buffers.
491 1.1 christos #
492 1.1 christos # The key here is that the regexes use start-of-buffer anchors (^), ensuring
493 1.1 christos # that they match the entire buffer, confirming that there was nothing in it
494 1.1 christos # before.
495 1.1 christos
496 1.1 christos proc ensure_no_output { test } {
497 1.1 christos global gdb_spawn_id gdb_main_spawn_id mi_spawn_id
498 1.1 christos global decimal
499 1.1 christos
500 1.1 christos if { $gdb_spawn_id == $gdb_main_spawn_id } {
501 1.1 christos # CLI
502 1.1 christos gdb_test "print 666" \
503 1.1.1.6 christos "^\\\$$decimal = 666" \
504 1.1 christos "$test, ensure no output CLI"
505 1.1 christos } elseif { $gdb_spawn_id == $mi_spawn_id } {
506 1.1 christos # MI
507 1.1 christos mi_gdb_test "777-data-evaluate-expression 888" \
508 1.1 christos "^777-data-evaluate-expression 888\r\n777\\^done,value=\"888\"" \
509 1.1 christos "$test, ensure no output MI"
510 1.1 christos } else {
511 1.1 christos error "Unexpected gdb_spawn_id value."
512 1.1 christos }
513 1.1 christos }
514 1.1 christos
515 1.1 christos # Match a regular expression, or ensure that there was no output.
516 1.1 christos #
517 1.1 christos # If RE is non-empty, try to match the content of the program output (using the
518 1.1 christos # current spawn_id) and pass/fail TEST accordingly.
519 1.1 christos # If RE is empty, ensure that the program did not output anything.
520 1.1 christos
521 1.1.1.5 christos proc match_re_or_ensure_no_output { re test } {
522 1.1 christos if { $re != "" } {
523 1.1 christos gdb_expect {
524 1.1 christos -re "$re" {
525 1.1 christos pass $test
526 1.1 christos }
527 1.1 christos
528 1.1 christos default {
529 1.1 christos fail $test
530 1.1 christos }
531 1.1 christos }
532 1.1 christos } else {
533 1.1 christos ensure_no_output $test
534 1.1 christos }
535 1.1 christos }
536 1.1 christos
537 1.1 christos # Test selecting an inferior from CLI.
538 1.1 christos
539 1.1.1.2 christos proc_with_prefix test_cli_inferior { mode } {
540 1.1 christos global gdb_main_spawn_id mi_spawn_id
541 1.1 christos
542 1.1 christos reset_selection "1.1"
543 1.1 christos
544 1.1 christos set mi_re [make_mi_re $mode 4 2 event]
545 1.1 christos set cli_re [make_cli_re $mode 2 2.1 2]
546 1.1 christos
547 1.1 christos flush_buffers
548 1.1 christos
549 1.1 christos # Do the 'inferior' command.
550 1.1 christos with_spawn_id $gdb_main_spawn_id {
551 1.1 christos gdb_test "inferior 2" $cli_re "CLI select inferior"
552 1.1 christos }
553 1.1 christos
554 1.1 christos with_spawn_id $mi_spawn_id {
555 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "event on MI"
556 1.1 christos }
557 1.1 christos
558 1.1 christos # Do the 'inferior' command on the currently selected inferior. For now,
559 1.1 christos # GDB naively re-outputs everything.
560 1.1 christos with_spawn_id $gdb_main_spawn_id {
561 1.1 christos gdb_test "inferior 2" $cli_re "CLI select inferior again"
562 1.1 christos }
563 1.1 christos
564 1.1 christos with_spawn_id $mi_spawn_id {
565 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "event on MI again"
566 1.1 christos }
567 1.1 christos }
568 1.1 christos
569 1.1 christos # Test thread selection from CLI.
570 1.1 christos
571 1.1.1.2 christos proc_with_prefix test_cli_thread { mode } {
572 1.1 christos global gdb_main_spawn_id
573 1.1 christos global mi_spawn_id
574 1.1 christos
575 1.1 christos set any "\[^\r\n\]*"
576 1.1 christos
577 1.1 christos reset_selection "1.1"
578 1.1 christos flush_buffers
579 1.1 christos
580 1.1 christos with_test_prefix "thread 1.2" {
581 1.1 christos # Do the 'thread' command to select a stopped thread.
582 1.1 christos
583 1.1 christos set mi_re [make_mi_re $mode 2 0 event]
584 1.1 christos set cli_re [make_cli_re $mode -1 1.2 0]
585 1.1 christos
586 1.1 christos with_spawn_id $gdb_main_spawn_id {
587 1.1 christos gdb_test "thread 1.2" $cli_re "select thread"
588 1.1 christos }
589 1.1 christos
590 1.1 christos with_spawn_id $mi_spawn_id {
591 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "select thread, event on MI "
592 1.1 christos }
593 1.1 christos
594 1.1 christos # Do the 'thread' command to select the same thread. We shouldn't receive
595 1.1 christos # an event on MI, since we won't actually switch thread.
596 1.1 christos
597 1.1 christos set mi_re ""
598 1.1 christos
599 1.1 christos with_spawn_id $gdb_main_spawn_id {
600 1.1 christos gdb_test "thread 1.2" $cli_re "select thread again"
601 1.1 christos }
602 1.1 christos
603 1.1 christos with_spawn_id $mi_spawn_id {
604 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "select thread, event on MI again"
605 1.1 christos }
606 1.1 christos
607 1.1 christos # Try the 'thread' command without arguments.
608 1.1 christos
609 1.1 christos set cli_re "\\\[Current thread is 1\\.2.*\\\]"
610 1.1 christos set mi_re ""
611 1.1 christos
612 1.1 christos with_spawn_id $gdb_main_spawn_id {
613 1.1 christos gdb_test "thread" $cli_re "thread without args"
614 1.1 christos }
615 1.1 christos
616 1.1 christos with_spawn_id $mi_spawn_id {
617 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "thread without args, event on MI"
618 1.1 christos }
619 1.1 christos }
620 1.1 christos
621 1.1 christos with_test_prefix "thread 1.3" {
622 1.1 christos # Do the 'thread' command to select the third thread, stopped on all-stop,
623 1.1 christos # running on non-stop.
624 1.1 christos
625 1.1 christos if { $mode == "all-stop" } {
626 1.1 christos set cli_re [make_cli_re $mode -1 1.3 0]
627 1.1 christos set mi_re [make_mi_re $mode 3 0 event]
628 1.1 christos } else {
629 1.1 christos set cli_re [make_cli_re $mode -1 1.3 -1]
630 1.1 christos set mi_re [make_mi_re $mode 3 -1 event]
631 1.1 christos }
632 1.1 christos
633 1.1 christos with_spawn_id $gdb_main_spawn_id {
634 1.1 christos gdb_test "thread 1.3" $cli_re "select thread"
635 1.1 christos }
636 1.1 christos
637 1.1 christos with_spawn_id $mi_spawn_id {
638 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "select thread, event on MI"
639 1.1 christos }
640 1.1 christos
641 1.1 christos # Do the 'thread' command to select the third thread again. Again, we
642 1.1 christos # shouldn't receive an event on MI.
643 1.1 christos
644 1.1 christos set mi_re ""
645 1.1 christos
646 1.1 christos with_spawn_id $gdb_main_spawn_id {
647 1.1 christos gdb_test "thread 1.3" $cli_re "select thread again"
648 1.1 christos }
649 1.1 christos
650 1.1 christos with_spawn_id $mi_spawn_id {
651 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "select thread again, event on MI"
652 1.1 christos }
653 1.1 christos
654 1.1 christos # Try the 'thread' command without arguments.
655 1.1 christos
656 1.1 christos set cli_re "\\\[Current thread is 1\\.3 ${any}\\\]"
657 1.1 christos set mi_re ""
658 1.1 christos
659 1.1 christos with_spawn_id $gdb_main_spawn_id {
660 1.1 christos gdb_test "thread" $cli_re "thread without args"
661 1.1 christos }
662 1.1 christos
663 1.1 christos with_spawn_id $mi_spawn_id {
664 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "thread without args, event on MI"
665 1.1 christos }
666 1.1 christos }
667 1.1 christos
668 1.1 christos # Idea for the future: selecting a thread in a different inferior. For now,
669 1.1 christos # GDB doesn't show an inferior switch, but if it did, it would be a nice
670 1.1 christos # place to test it.
671 1.1 christos }
672 1.1 christos
673 1.1 christos # Test frame selection from CLI.
674 1.1 christos
675 1.1.1.2 christos proc_with_prefix test_cli_frame { mode } {
676 1.1 christos global gdb_main_spawn_id mi_spawn_id
677 1.1 christos
678 1.1 christos with_test_prefix "thread 1.2" {
679 1.1 christos reset_selection "1.2"
680 1.1 christos flush_buffers
681 1.1 christos
682 1.1 christos # Do the 'frame' command to select frame 1.
683 1.1 christos
684 1.1 christos set mi_re [make_mi_re $mode 2 1 event]
685 1.1 christos set cli_re [make_cli_re $mode -1 -1 1]
686 1.1 christos
687 1.1 christos with_spawn_id $gdb_main_spawn_id {
688 1.1 christos gdb_test "frame 1" $cli_re "select frame 1"
689 1.1 christos }
690 1.1 christos
691 1.1 christos with_spawn_id $mi_spawn_id {
692 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "select frame 1, event on MI"
693 1.1 christos }
694 1.1 christos
695 1.1 christos # Do the 'frame' command to select the same frame. This time we don't
696 1.1 christos # expect an event on MI, since we won't actually change frame.
697 1.1 christos
698 1.1 christos set mi_re ""
699 1.1 christos
700 1.1 christos with_spawn_id $gdb_main_spawn_id {
701 1.1 christos gdb_test "frame 1" $cli_re "select frame 1 again"
702 1.1 christos }
703 1.1 christos
704 1.1 christos with_spawn_id $mi_spawn_id {
705 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "select frame 1 again, event on MI"
706 1.1 christos }
707 1.1 christos
708 1.1 christos # Do the 'frame' command without arguments. We shouldn't see anything on MI.
709 1.1 christos
710 1.1 christos with_spawn_id $gdb_main_spawn_id {
711 1.1 christos gdb_test "frame" $cli_re "frame without args"
712 1.1 christos }
713 1.1 christos
714 1.1 christos with_spawn_id $mi_spawn_id {
715 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "frame without args, event on MI"
716 1.1 christos }
717 1.1 christos }
718 1.1 christos
719 1.1 christos with_test_prefix "thread 1.3" {
720 1.1 christos # Now, try the 'frame' command on thread 3, which is running if we are in
721 1.1 christos # non-stop mode.
722 1.1 christos reset_selection "1.3"
723 1.1 christos flush_buffers
724 1.1 christos
725 1.1 christos if {$mode == "all-stop"} {
726 1.1 christos set mi_re [make_mi_re $mode 3 1 event]
727 1.1 christos set cli_re [make_cli_re $mode -1 -1 1]
728 1.1 christos } elseif {$mode == "non-stop"} {
729 1.1 christos set mi_re ""
730 1.1 christos set cli_re "Selected thread is running\\."
731 1.1 christos }
732 1.1 christos
733 1.1 christos with_spawn_id $gdb_main_spawn_id {
734 1.1 christos gdb_test "frame 1" $cli_re "select frame 1"
735 1.1 christos }
736 1.1 christos
737 1.1 christos with_spawn_id $mi_spawn_id {
738 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "select frame 1, event on MI"
739 1.1 christos }
740 1.1 christos
741 1.1 christos # Do the 'frame' command without arguments.
742 1.1 christos
743 1.1 christos if { $mode == "non-stop" } {
744 1.1 christos set cli_re "No stack\\."
745 1.1 christos }
746 1.1 christos set mi_re ""
747 1.1 christos
748 1.1 christos with_spawn_id $gdb_main_spawn_id {
749 1.1 christos gdb_test "frame" $cli_re "frame without args"
750 1.1 christos }
751 1.1 christos
752 1.1 christos with_spawn_id $mi_spawn_id {
753 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "frame without args, event on MI"
754 1.1 christos }
755 1.1 christos }
756 1.1 christos }
757 1.1 christos
758 1.1 christos # Test frame selection from CLI with the select-frame command.
759 1.1 christos
760 1.1.1.2 christos proc_with_prefix test_cli_select_frame { mode } {
761 1.1 christos global gdb_main_spawn_id mi_spawn_id expect_out
762 1.1 christos
763 1.1 christos with_test_prefix "thread 1.2" {
764 1.1 christos reset_selection "1.2"
765 1.1 christos flush_buffers
766 1.1 christos
767 1.1 christos # Do the 'select-frame' command to select frame 1.
768 1.1 christos
769 1.1 christos set mi_re [make_mi_re $mode 2 1 event]
770 1.1 christos
771 1.1 christos with_spawn_id $gdb_main_spawn_id {
772 1.1 christos gdb_test_no_output "select-frame 1" "select frame 1"
773 1.1 christos }
774 1.1 christos
775 1.1 christos with_spawn_id $mi_spawn_id {
776 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "select frame 1, event on MI"
777 1.1 christos }
778 1.1 christos
779 1.1 christos # Do the 'select-frame' command to select the same frame. This time we expect to
780 1.1 christos # event on MI, since we won't actually change frame.
781 1.1 christos
782 1.1 christos set mi_re ""
783 1.1 christos
784 1.1 christos with_spawn_id $gdb_main_spawn_id {
785 1.1 christos gdb_test_no_output "select-frame 1" "select frame 1 again"
786 1.1 christos }
787 1.1 christos
788 1.1 christos with_spawn_id $mi_spawn_id {
789 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "select frame 1 again, event on MI"
790 1.1 christos }
791 1.1 christos }
792 1.1 christos
793 1.1 christos with_test_prefix "thread 1.3" {
794 1.1 christos # Now, try the 'select-frame' command on thread 3, which is running if we are in
795 1.1 christos # non-stop mode.
796 1.1 christos reset_selection "1.3"
797 1.1 christos flush_buffers
798 1.1 christos
799 1.1 christos if {$mode == "all-stop"} {
800 1.1 christos set mi_re [make_mi_re $mode 3 1 event]
801 1.1 christos } elseif {$mode == "non-stop"} {
802 1.1 christos set mi-re ""
803 1.1 christos set cli_re "Selected thread is running\\."
804 1.1 christos }
805 1.1 christos
806 1.1 christos with_spawn_id $gdb_main_spawn_id {
807 1.1 christos if { $mode == "all-stop" } {
808 1.1 christos gdb_test_no_output "select-frame 1" "select frame 1"
809 1.1 christos } else {
810 1.1 christos gdb_test "select-frame 1" $cli_re "select frame 1"
811 1.1 christos }
812 1.1 christos }
813 1.1 christos
814 1.1 christos with_spawn_id $mi_spawn_id {
815 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "select frame 1, event on MI"
816 1.1 christos }
817 1.1 christos }
818 1.1 christos }
819 1.1 christos
820 1.1 christos # Test doing an up and then down command from CLI.
821 1.1 christos
822 1.1.1.2 christos proc_with_prefix test_cli_up_down { mode } {
823 1.1 christos global gdb_main_spawn_id mi_spawn_id
824 1.1 christos
825 1.1 christos reset_selection "1.2"
826 1.1 christos flush_buffers
827 1.1 christos
828 1.1 christos # Try doing an 'up'.
829 1.1 christos
830 1.1 christos set mi_re [make_mi_re $mode 2 1 event]
831 1.1 christos set cli_re [make_cli_re $mode -1 -1 1]
832 1.1 christos
833 1.1 christos with_spawn_id $gdb_main_spawn_id {
834 1.1 christos gdb_test "up" $cli_re "frame up"
835 1.1 christos }
836 1.1 christos
837 1.1 christos with_spawn_id $mi_spawn_id {
838 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "frame up, event on MI"
839 1.1 christos }
840 1.1 christos
841 1.1 christos # Try doing a 'down'.
842 1.1 christos
843 1.1 christos set mi_re [make_mi_re $mode 2 0 event]
844 1.1 christos set cli_re [make_cli_re $mode -1 -1 0]
845 1.1 christos
846 1.1 christos with_spawn_id $gdb_main_spawn_id {
847 1.1 christos gdb_test "down" $cli_re "frame down"
848 1.1 christos }
849 1.1 christos
850 1.1 christos with_spawn_id $mi_spawn_id {
851 1.1.1.5 christos match_re_or_ensure_no_output $mi_re "frame down, event on MI"
852 1.1 christos }
853 1.1 christos }
854 1.1 christos
855 1.1 christos # Test selecting a thread from MI.
856 1.1 christos
857 1.1.1.2 christos proc_with_prefix test_mi_thread_select { mode } {
858 1.1 christos global gdb_main_spawn_id mi_spawn_id
859 1.1 christos
860 1.1 christos reset_selection "1.1"
861 1.1 christos flush_buffers
862 1.1 christos
863 1.1 christos with_test_prefix "thread 1.2" {
864 1.1 christos # Do the '-thread-select' command to select a stopped thread.
865 1.1 christos
866 1.1 christos set mi_re [make_mi_re $mode 2 0 response]
867 1.1 christos set cli_re [make_cli_re $mode -1 1.2 0]
868 1.1 christos
869 1.1 christos with_spawn_id $mi_spawn_id {
870 1.1 christos mi_gdb_test "-thread-select 2" $mi_re "-thread-select"
871 1.1 christos }
872 1.1 christos
873 1.1 christos with_spawn_id $gdb_main_spawn_id {
874 1.1.1.5 christos match_re_or_ensure_no_output "$cli_re\r\n" "-thread-select, event on CLI"
875 1.1 christos }
876 1.1 christos
877 1.1 christos # Do the '-thread-select' command to select the same thread. We
878 1.1 christos # shouldn't receive an event on CLI, since we won't actually switch
879 1.1 christos # thread.
880 1.1 christos
881 1.1 christos set cli_re ""
882 1.1 christos
883 1.1 christos with_spawn_id $mi_spawn_id {
884 1.1 christos mi_gdb_test "-thread-select 2" $mi_re "-thread-select again"
885 1.1 christos }
886 1.1 christos
887 1.1 christos with_spawn_id $gdb_main_spawn_id {
888 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "-thread-select again, event on CLI"
889 1.1 christos }
890 1.1 christos }
891 1.1 christos
892 1.1 christos with_test_prefix "thread 1.3" {
893 1.1 christos # Do the '-thread-select' command to select the third thread, stopped on all-stop,
894 1.1 christos # running on non-stop.
895 1.1 christos
896 1.1 christos if { $mode == "all-stop" } {
897 1.1 christos set mi_re [make_mi_re $mode 3 0 response]
898 1.1 christos set cli_re [make_cli_re $mode -1 1.3 0]
899 1.1 christos } else {
900 1.1 christos set mi_re [make_mi_re $mode 3 -1 response]
901 1.1 christos set cli_re [make_cli_re $mode -1 1.3 -1]
902 1.1 christos }
903 1.1 christos
904 1.1 christos with_spawn_id $mi_spawn_id {
905 1.1 christos mi_gdb_test "-thread-select 3" $mi_re "-thread-select"
906 1.1 christos }
907 1.1 christos
908 1.1 christos with_spawn_id $gdb_main_spawn_id {
909 1.1.1.5 christos match_re_or_ensure_no_output "$cli_re\r\n" "-thread-select, event on CLI"
910 1.1 christos }
911 1.1 christos
912 1.1 christos # Do the 'thread' command to select the third thread again. Again, we
913 1.1 christos # shouldn't receive an event on MI.
914 1.1 christos
915 1.1 christos set cli_re ""
916 1.1 christos
917 1.1 christos with_spawn_id $mi_spawn_id {
918 1.1 christos mi_gdb_test "-thread-select 3" $mi_re "-thread-select again"
919 1.1 christos }
920 1.1 christos
921 1.1 christos with_spawn_id $gdb_main_spawn_id {
922 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "-thread-select again, event on CLI"
923 1.1 christos }
924 1.1 christos }
925 1.1 christos
926 1.1.1.5 christos with_test_prefix "thread 1.2 with --thread 2" {
927 1.1 christos # Test selecting a thread from MI with a --thread option. This test
928 1.1.1.5 christos # verifies that even if the thread GDB would switch to is the same as
929 1.1 christos # the thread specified with --thread, an event is still sent to CLI.
930 1.1 christos # In this case this is thread 1.2
931 1.1 christos
932 1.1 christos set mi_re [make_mi_re $mode 2 0 response]
933 1.1 christos set cli_re [make_cli_re $mode -1 1.2 0]
934 1.1 christos
935 1.1 christos with_spawn_id $mi_spawn_id {
936 1.1 christos mi_gdb_test "-thread-select --thread 2 2" $mi_re "-thread-select"
937 1.1 christos }
938 1.1 christos
939 1.1 christos with_spawn_id $gdb_main_spawn_id {
940 1.1.1.5 christos match_re_or_ensure_no_output "$cli_re\r\n" "-thread-select, event on cli"
941 1.1.1.5 christos }
942 1.1.1.5 christos }
943 1.1.1.5 christos
944 1.1.1.5 christos with_test_prefix "thread 1.2 with --thread 3" {
945 1.1.1.5 christos # Test selecting a thread from MI with a --thread option.
946 1.1.1.5 christos # This test verifies that when different thread numbers are
947 1.1.1.5 christos # passed to the --thread option and the underlying
948 1.1.1.5 christos # -thread-select command, the correct thread is selected.
949 1.1.1.5 christos # In this case this is thread 1.2
950 1.1.1.5 christos
951 1.1.1.5 christos reset_selection "1.1"
952 1.1.1.5 christos
953 1.1.1.5 christos set mi_re [make_mi_re $mode 2 0 response]
954 1.1.1.5 christos set cli_re [make_cli_re $mode -1 1.2 0]
955 1.1.1.5 christos
956 1.1.1.5 christos with_spawn_id $mi_spawn_id {
957 1.1.1.5 christos mi_gdb_test "-thread-select --thread 3 2" $mi_re "-thread-select"
958 1.1.1.5 christos }
959 1.1.1.5 christos
960 1.1.1.5 christos with_spawn_id $gdb_main_spawn_id {
961 1.1.1.5 christos match_re_or_ensure_no_output "$cli_re\r\n" "-thread-select, event on cli"
962 1.1 christos }
963 1.1 christos }
964 1.1 christos
965 1.1 christos # Idea for the future: selecting a thread in a different inferior. For now,
966 1.1 christos # GDB doesn't show an inferior switch, but if it did, it would be a nice
967 1.1 christos # place to test it.
968 1.1 christos }
969 1.1 christos
970 1.1.1.2 christos proc_with_prefix test_mi_stack_select_frame { mode } {
971 1.1 christos global gdb_main_spawn_id mi_spawn_id
972 1.1 christos
973 1.1 christos with_test_prefix "thread 1.2" {
974 1.1 christos reset_selection "1.2"
975 1.1 christos flush_buffers
976 1.1 christos
977 1.1 christos # Do the '-stack-select-frame' command to select frame 1.
978 1.1 christos
979 1.1 christos set mi_re "\\^done"
980 1.1 christos set cli_re [make_cli_re $mode -1 -1 1]
981 1.1 christos
982 1.1 christos with_spawn_id $mi_spawn_id {
983 1.1 christos mi_gdb_test "-stack-select-frame 1" $mi_re "-stack-select-frame"
984 1.1 christos }
985 1.1 christos
986 1.1 christos with_spawn_id $gdb_main_spawn_id {
987 1.1.1.5 christos match_re_or_ensure_no_output "$cli_re\r\n" "-stack-select-frame, event on CLI"
988 1.1 christos }
989 1.1 christos
990 1.1 christos # Do the '-stack-select-frame' command to select the same frame. This time we don't
991 1.1 christos # expect an event on CLI, since we won't actually change frame.
992 1.1 christos
993 1.1 christos set cli_re ""
994 1.1 christos
995 1.1 christos with_spawn_id $mi_spawn_id {
996 1.1 christos mi_gdb_test "-stack-select-frame 1" $mi_re "-stack-select-frame again"
997 1.1 christos }
998 1.1 christos
999 1.1 christos with_spawn_id $gdb_main_spawn_id {
1000 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "-stack-select-frame again, event on CLI"
1001 1.1.1.5 christos }
1002 1.1.1.5 christos
1003 1.1.1.5 christos # Now use the '-stack-select-frame' command with the --frame
1004 1.1.1.5 christos # option, this verifies that even when the frame GDB would
1005 1.1.1.5 christos # swith to is the same as the frame specified with --frame, an
1006 1.1.1.5 christos # event is still sent to the CLI.
1007 1.1.1.5 christos
1008 1.1.1.5 christos set cli_re [make_cli_re $mode -1 -1 0]
1009 1.1.1.5 christos
1010 1.1.1.5 christos with_spawn_id $mi_spawn_id {
1011 1.1.1.5 christos mi_gdb_test "-stack-select-frame --thread 2 --frame 0 0" $mi_re
1012 1.1.1.5 christos }
1013 1.1.1.5 christos
1014 1.1.1.5 christos with_spawn_id $gdb_main_spawn_id {
1015 1.1.1.5 christos match_re_or_ensure_no_output "$cli_re\r\n" "-stack-select-frame with --frame 0, event on CLI"
1016 1.1.1.5 christos }
1017 1.1.1.5 christos
1018 1.1.1.5 christos # Now use the '-stack-select-frame' command with the --frame
1019 1.1.1.5 christos # option, this verifies that the correct event is sent to the
1020 1.1.1.5 christos # CLI when the frame specified with --frame is different to
1021 1.1.1.5 christos # the actual frame selected.
1022 1.1.1.5 christos
1023 1.1.1.5 christos set cli_re [make_cli_re $mode -1 -1 1]
1024 1.1.1.5 christos
1025 1.1.1.5 christos with_spawn_id $mi_spawn_id {
1026 1.1.1.5 christos mi_gdb_test "-stack-select-frame --thread 2 --frame 2 1" $mi_re
1027 1.1.1.5 christos }
1028 1.1.1.5 christos
1029 1.1.1.5 christos with_spawn_id $gdb_main_spawn_id {
1030 1.1.1.5 christos match_re_or_ensure_no_output "$cli_re\r\n" "-stack-select-frame with --frame 2, event on CLI"
1031 1.1 christos }
1032 1.1 christos }
1033 1.1 christos
1034 1.1 christos with_test_prefix "thread 1.3" {
1035 1.1 christos # Now, try the '-stack-select-frame' command on thread 3, which is
1036 1.1 christos # running if we are in non-stop mode.
1037 1.1 christos reset_selection "1.3"
1038 1.1 christos flush_buffers
1039 1.1 christos
1040 1.1 christos if {$mode == "all-stop"} {
1041 1.1 christos set mi_re "\\^done"
1042 1.1 christos set cli_re [make_cli_re $mode -1 -1 1]
1043 1.1 christos append cli_re "\r\n"
1044 1.1 christos } elseif {$mode == "non-stop"} {
1045 1.1 christos set cli_re ""
1046 1.1 christos set mi_re "\\^error,msg=\"Selected thread is running\\.\""
1047 1.1 christos }
1048 1.1 christos
1049 1.1 christos with_spawn_id $mi_spawn_id {
1050 1.1 christos mi_gdb_test "-stack-select-frame 1" $mi_re "-stack-select-frame"
1051 1.1 christos }
1052 1.1 christos
1053 1.1 christos with_spawn_id $gdb_main_spawn_id {
1054 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "-stack-select-frame, event on CLI"
1055 1.1 christos }
1056 1.1 christos }
1057 1.1 christos }
1058 1.1 christos
1059 1.1 christos proc make_cli_in_mi_command { cli_in_mi_mode command } {
1060 1.1 christos if { $cli_in_mi_mode == "direct" } {
1061 1.1 christos return $command
1062 1.1 christos } elseif { $cli_in_mi_mode == "interpreter-exec" } {
1063 1.1 christos return "-interpreter-exec console \"$command\""
1064 1.1 christos } else {
1065 1.1 christos error "Invalid value for CLI_IN_MI_MODE."
1066 1.1 christos }
1067 1.1 christos }
1068 1.1 christos
1069 1.1 christos # Test selecting the inferior using a CLI command in the MI channel.
1070 1.1 christos
1071 1.1.1.2 christos proc_with_prefix test_cli_in_mi_inferior { mode cli_in_mi_mode } {
1072 1.1 christos global gdb_main_spawn_id mi_spawn_id
1073 1.1 christos
1074 1.1 christos reset_selection "1.1"
1075 1.1 christos flush_buffers
1076 1.1 christos
1077 1.1 christos set command [make_cli_in_mi_command $cli_in_mi_mode "inferior 2"]
1078 1.1 christos
1079 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 2 2.1 4 2]
1080 1.1 christos set cli_re [make_cli_re $mode 2 "2.1" 2]
1081 1.1 christos
1082 1.1 christos with_spawn_id $mi_spawn_id {
1083 1.1 christos mi_gdb_test $command $mi_re "select inferior"
1084 1.1 christos }
1085 1.1 christos
1086 1.1 christos with_spawn_id $gdb_main_spawn_id {
1087 1.1.1.5 christos match_re_or_ensure_no_output "$cli_re\r\n" "select inferior, event on CLI"
1088 1.1 christos }
1089 1.1 christos
1090 1.1 christos # Do the 'inferior' command on the currently selected inferior. For now,
1091 1.1 christos # GDB naively re-outputs everything.
1092 1.1 christos with_spawn_id $mi_spawn_id {
1093 1.1 christos mi_gdb_test $command $mi_re "select inferior again"
1094 1.1 christos }
1095 1.1 christos
1096 1.1 christos with_spawn_id $gdb_main_spawn_id {
1097 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "select inferior again, event on CLI"
1098 1.1 christos }
1099 1.1 christos }
1100 1.1 christos
1101 1.1 christos # Test selecting the thread using a CLI command in the MI channel.
1102 1.1 christos
1103 1.1.1.2 christos proc_with_prefix test_cli_in_mi_thread { mode cli_in_mi_mode } {
1104 1.1 christos global gdb_main_spawn_id mi_spawn_id
1105 1.1 christos
1106 1.1 christos reset_selection "1.1"
1107 1.1 christos flush_buffers
1108 1.1 christos
1109 1.1 christos with_test_prefix "thread 1.2" {
1110 1.1 christos # Do the 'thread' command to select a stopped thread.
1111 1.1 christos
1112 1.1 christos set command [make_cli_in_mi_command $cli_in_mi_mode "thread 1.2"]
1113 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 -1 1.2 2 0]
1114 1.1 christos set cli_re [make_cli_re $mode -1 1.2 0]
1115 1.1 christos
1116 1.1 christos with_spawn_id $mi_spawn_id {
1117 1.1 christos mi_gdb_test $command $mi_re "select thread"
1118 1.1 christos }
1119 1.1 christos
1120 1.1 christos with_spawn_id $gdb_main_spawn_id {
1121 1.1.1.5 christos match_re_or_ensure_no_output "$cli_re\r\n" "select thread, event on CLI"
1122 1.1 christos }
1123 1.1 christos
1124 1.1 christos # Do the 'thread' command to select the same thread. We shouldn't
1125 1.1 christos # receive an event on CLI, since we won't actually switch thread.
1126 1.1 christos
1127 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 1.2 2 0]
1128 1.1 christos set cli_re ""
1129 1.1 christos
1130 1.1 christos with_spawn_id $mi_spawn_id {
1131 1.1 christos mi_gdb_test $command $mi_re "select thread again"
1132 1.1 christos }
1133 1.1 christos
1134 1.1 christos with_spawn_id $gdb_main_spawn_id {
1135 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "select thread again, event on CLI"
1136 1.1 christos }
1137 1.1 christos
1138 1.1 christos # Try the 'thread' command without arguments.
1139 1.1 christos
1140 1.1 christos set command [make_cli_in_mi_command $cli_in_mi_mode "thread"]
1141 1.1 christos
1142 1.1 christos set mi_re "${command}.*~\"\\\[Current thread is 1\\.2.*\\\]\\\\n\".*\\^done"
1143 1.1 christos set cli_re ""
1144 1.1 christos
1145 1.1 christos with_spawn_id $mi_spawn_id {
1146 1.1 christos mi_gdb_test $command $mi_re "thread without args"
1147 1.1 christos }
1148 1.1 christos
1149 1.1 christos with_spawn_id $gdb_main_spawn_id {
1150 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "thread without args, event on CLI"
1151 1.1 christos }
1152 1.1 christos }
1153 1.1 christos
1154 1.1 christos with_test_prefix "thread 1.3" {
1155 1.1 christos # Do the 'thread' command to select the third thread, stopped on
1156 1.1 christos # all-stop, running on non-stop.
1157 1.1 christos
1158 1.1 christos set command [make_cli_in_mi_command $cli_in_mi_mode "thread 1.3"]
1159 1.1 christos if { $mode == "all-stop" } {
1160 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 -1 1.3 3 0]
1161 1.1 christos set cli_re [make_cli_re $mode -1 "1.3" 0]
1162 1.1 christos } else {
1163 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 -1 1.3 3 -1]
1164 1.1 christos set cli_re [make_cli_re $mode -1 "1.3" -1]
1165 1.1 christos }
1166 1.1 christos
1167 1.1 christos with_spawn_id $mi_spawn_id {
1168 1.1 christos mi_gdb_test $command $mi_re "select thread"
1169 1.1 christos }
1170 1.1 christos
1171 1.1 christos with_spawn_id $gdb_main_spawn_id {
1172 1.1.1.5 christos match_re_or_ensure_no_output "$cli_re\r\n" "select thread, event on CLI"
1173 1.1 christos }
1174 1.1 christos
1175 1.1 christos # Do the 'thread' command to select the third thread again. Again, we
1176 1.1 christos # shouldn't receive an event on MI.
1177 1.1 christos
1178 1.1 christos if { $mode == "all-stop" } {
1179 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 1.3 3 0]
1180 1.1 christos } else {
1181 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 1.3 3 -1]
1182 1.1 christos }
1183 1.1 christos set cli_re ""
1184 1.1 christos
1185 1.1 christos with_spawn_id $mi_spawn_id {
1186 1.1 christos mi_gdb_test $command $mi_re "select thread again"
1187 1.1 christos }
1188 1.1 christos
1189 1.1 christos with_spawn_id $gdb_main_spawn_id {
1190 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "select thread again, event on CLI"
1191 1.1 christos }
1192 1.1 christos
1193 1.1 christos # Try the 'thread' command without arguments.
1194 1.1 christos
1195 1.1 christos set command [make_cli_in_mi_command $cli_in_mi_mode "thread"]
1196 1.1 christos
1197 1.1 christos set mi_re "${command}.*~\"\\\[Current thread is 1\\.3.*\\\]\\\\n\".*\\^done"
1198 1.1 christos set cli_re ""
1199 1.1 christos
1200 1.1 christos with_spawn_id $mi_spawn_id {
1201 1.1 christos mi_gdb_test $command $mi_re "thread without args"
1202 1.1 christos }
1203 1.1 christos
1204 1.1 christos with_spawn_id $gdb_main_spawn_id {
1205 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "thread without args, event on CLI"
1206 1.1 christos }
1207 1.1 christos }
1208 1.1 christos
1209 1.1 christos # Idea for the future: selecting a thread in a different inferior. For now,
1210 1.1 christos # GDB doesn't show an inferior switch, but if it did, it would be a nice
1211 1.1 christos # place to test it.
1212 1.1 christos }
1213 1.1 christos
1214 1.1 christos # Test selecting the frame using a CLI command in the MI channel.
1215 1.1 christos
1216 1.1.1.2 christos proc_with_prefix test_cli_in_mi_frame { mode cli_in_mi_mode } {
1217 1.1 christos global gdb_main_spawn_id mi_spawn_id
1218 1.1 christos
1219 1.1 christos with_test_prefix "thread 1.2" {
1220 1.1 christos reset_selection "1.2"
1221 1.1 christos flush_buffers
1222 1.1 christos
1223 1.1 christos # Do the 'frame' command to select frame 1.
1224 1.1 christos
1225 1.1 christos set command [make_cli_in_mi_command $cli_in_mi_mode "frame 1"]
1226 1.1 christos set cli_re [make_cli_re $mode -1 -1 1]
1227 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 -1 -1 2 1]
1228 1.1 christos
1229 1.1 christos with_spawn_id $mi_spawn_id {
1230 1.1 christos mi_gdb_test $command $mi_re "select frame 1"
1231 1.1 christos }
1232 1.1 christos
1233 1.1 christos with_spawn_id $gdb_main_spawn_id {
1234 1.1.1.5 christos match_re_or_ensure_no_output "$cli_re\r\n" "select frame 1, event on CLI"
1235 1.1 christos }
1236 1.1 christos
1237 1.1 christos # Do the 'frame' command to select the same frame. This time we don't
1238 1.1 christos # expect an event on MI, since we won't actually change frame.
1239 1.1 christos
1240 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 -1 2 1]
1241 1.1 christos set cli_re ""
1242 1.1 christos
1243 1.1 christos with_spawn_id $mi_spawn_id {
1244 1.1 christos mi_gdb_test $command $mi_re "select frame 1 again"
1245 1.1 christos }
1246 1.1 christos
1247 1.1 christos with_spawn_id $gdb_main_spawn_id {
1248 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "select frame 1 again, event on CLI"
1249 1.1 christos }
1250 1.1 christos
1251 1.1 christos # Do the 'frame' command without arguments. We shouldn't see anything on MI.
1252 1.1 christos
1253 1.1 christos set command [make_cli_in_mi_command $cli_in_mi_mode "frame"]
1254 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 -1 2 1]
1255 1.1 christos
1256 1.1 christos with_spawn_id $mi_spawn_id {
1257 1.1 christos mi_gdb_test $command $mi_re "frame without args"
1258 1.1 christos }
1259 1.1 christos
1260 1.1 christos with_spawn_id $gdb_main_spawn_id {
1261 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "frame without args, event on CLI"
1262 1.1 christos }
1263 1.1 christos }
1264 1.1 christos
1265 1.1 christos with_test_prefix "thread 1.3" {
1266 1.1 christos # Now, try the 'frame' command on thread 3, which is running if we are in
1267 1.1 christos # non-stop mode.
1268 1.1 christos reset_selection "1.3"
1269 1.1 christos flush_buffers
1270 1.1 christos
1271 1.1 christos set command [make_cli_in_mi_command $cli_in_mi_mode "frame 1"]
1272 1.1 christos if {$mode == "all-stop"} {
1273 1.1 christos set cli_re [make_cli_re $mode -1 -1 1]
1274 1.1 christos append cli_re "\r\n"
1275 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 -1 -1 3 1]
1276 1.1 christos } elseif {$mode == "non-stop"} {
1277 1.1 christos set cli_re ""
1278 1.1 christos set mi_re "\\^error,msg=\"Selected thread is running\\.\".*"
1279 1.1 christos }
1280 1.1 christos
1281 1.1 christos with_spawn_id $mi_spawn_id {
1282 1.1 christos mi_gdb_test $command $mi_re "select frame 1"
1283 1.1 christos }
1284 1.1 christos
1285 1.1 christos with_spawn_id $gdb_main_spawn_id {
1286 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "select frame 1, event on CLI"
1287 1.1 christos }
1288 1.1 christos
1289 1.1 christos # Do the 'frame' command without arguments.
1290 1.1 christos
1291 1.1 christos set command [make_cli_in_mi_command $cli_in_mi_mode "frame"]
1292 1.1 christos if { $mode == "all-stop" } {
1293 1.1 christos set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 -1 -1 1]
1294 1.1 christos } else {
1295 1.1 christos set mi_re "\\^error,msg=\"No stack\\.\""
1296 1.1 christos }
1297 1.1 christos set cli_re ""
1298 1.1 christos
1299 1.1 christos with_spawn_id $mi_spawn_id {
1300 1.1 christos mi_gdb_test $command $mi_re "frame without args"
1301 1.1 christos }
1302 1.1 christos
1303 1.1 christos with_spawn_id $gdb_main_spawn_id {
1304 1.1.1.5 christos match_re_or_ensure_no_output $cli_re "frame without args, event on CLI"
1305 1.1 christos }
1306 1.1 christos }
1307 1.1 christos }
1308 1.1 christos
1309 1.1 christos foreach_with_prefix mode { "all-stop" "non-stop" } {
1310 1.1.1.5 christos set test "setup done"
1311 1.1.1.5 christos if { [test_setup $mode] == -1 } {
1312 1.1.1.5 christos fail $test
1313 1.1.1.5 christos continue
1314 1.1.1.5 christos }
1315 1.1.1.5 christos pass $test
1316 1.1 christos
1317 1.1 christos # Test selecting inferior, thread and frame from CLI
1318 1.1 christos
1319 1.1.1.2 christos test_cli_inferior $mode
1320 1.1.1.2 christos test_cli_thread $mode
1321 1.1.1.2 christos test_cli_frame $mode
1322 1.1.1.2 christos test_cli_select_frame $mode
1323 1.1.1.2 christos test_cli_up_down $mode
1324 1.1 christos
1325 1.1 christos # Test selecting thread and frame from MI
1326 1.1 christos
1327 1.1.1.2 christos test_mi_thread_select $mode
1328 1.1.1.2 christos test_mi_stack_select_frame $mode
1329 1.1 christos
1330 1.1 christos # Test some CLI commands sent through MI, both with a "direct" command,
1331 1.1 christos # such as "thread 1", and with -interpreter-exec, such as
1332 1.1 christos # '-interpreter-exec console "thread 1"'.
1333 1.1 christos
1334 1.1 christos foreach_with_prefix exec_mode {"direct" "interpreter-exec"} {
1335 1.1.1.2 christos test_cli_in_mi_inferior $mode $exec_mode
1336 1.1.1.2 christos test_cli_in_mi_thread $mode $exec_mode
1337 1.1.1.2 christos test_cli_in_mi_frame $mode $exec_mode
1338 1.1 christos }
1339 1.1 christos }
1340