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