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