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