Make gdb.mi/user-selected-context-sync.exp use proc_with_prefix
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.mi / user-selected-context-sync.exp
1 # Copyright 2016 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 # 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 load_lib mi-support.exp
33
34 standard_testfile
35
36 # Multiple inferiors are needed, therefore only native gdb and extended
37 # gdbserver modes are supported.
38 if [use_gdb_stub] {
39 untested ${testfile}.exp
40 return
41 }
42
43 set compile_options "debug pthreads"
44 if {[build_executable $testfile.exp $testfile ${srcfile} ${compile_options}] == -1} {
45 untested "failed to compile $testfile"
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\"\}"
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\"\}"
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}\"\}"
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 mi_expect_stop "breakpoint-hit" "main" "" "$srcfile" \
305 "$decimal" {"" "disp=\"del\""} "stop at breakpoint in main"
306 }
307
308 if { $mode == "all-stop" } {
309 set previous_schedlock_val [show_scheduler_locking]
310
311 # Set scheduler-locking on, so that we can control threads
312 # independently.
313 gdb_test_no_output "set scheduler-locking on"
314
315 # Continue each child thread to the point we want them to be.
316 foreach thread { 2 3 } {
317 gdb_test "thread $inf.$thread" ".*" "select child thread $inf.$thread"
318
319 gdb_test "tbreak $srcfile:$thread_loop_line" \
320 "Temporary breakpoint ${any}" \
321 "set breakpoint for thread $inf.$thread"
322
323 gdb_continue_to_breakpoint "continue thread $inf.$thread to infinite loop breakpoint"
324
325 # Consume MI output.
326 with_spawn_id $mi_spawn_id {
327 mi_expect_stop "breakpoint-hit" "child_sub_function" \
328 "" "$srcfile" "$decimal" {"" "disp=\"del\""} \
329 "thread $inf.$thread stops MI"
330 }
331 }
332
333 # Restore scheduler-locking to its original value.
334 gdb_test_no_output "set scheduler-locking $previous_schedlock_val"
335 } else { # $mode == "non-stop"
336 # Put a thread-specific breakpoint for thread 2 of the current
337 # inferior. We don't put a breakpoint for thread 3, since we
338 # want to let it run.
339 set test "set thread-specific breakpoint, thread $inf.2"
340 gdb_test_multiple "tbreak $srcfile:$thread_loop_line thread $inf.2" $test {
341 -re "Temporary breakpoint ${any}\r\n$gdb_prompt " {
342 pass $test
343 }
344 }
345
346 # Confirm the stop of thread $inf.2.
347 set test "thread $inf.2 stops CLI"
348 gdb_test_multiple "" $test {
349 -re "Thread $inf.2 ${any} hit Temporary breakpoint ${any}\r\n$thread_loop_line${any}\r\n" {
350 pass $test
351 }
352 }
353
354 # Consume MI output.
355 with_spawn_id $mi_spawn_id {
356 mi_expect_stop "breakpoint-hit" "child_sub_function" \
357 "" "$srcfile" "$decimal" {"" "disp=\"del\""} \
358 "thread $inf.2 stops MI"
359 }
360 }
361 }
362 }
363 }
364
365 # Prepare the test environment.
366 #
367 # MODE can be either "all-stop" or "non-stop".
368
369 proc_with_prefix test_setup { mode } {
370 global srcfile
371 global srcdir
372 global subdir
373 global gdb_main_spawn_id
374 global mi_spawn_id
375 global decimal
376 global binfile
377 global GDBFLAGS
378 global async
379
380 set any "\[^\r\n\]*"
381
382 mi_gdb_exit
383
384 save_vars { GDBFLAGS } {
385 if { $mode == "non-stop" } {
386 set GDBFLAGS [concat $GDBFLAGS " -ex \"set non-stop 1\""]
387 }
388
389 if { [mi_gdb_start "separate-mi-tty"] != 0 } {
390 return
391 }
392 }
393
394 mi_delete_breakpoints
395 mi_gdb_reinitialize_dir $srcdir/$subdir
396 mi_gdb_load $binfile
397
398 if { [mi_runto main] < 0 } {
399 fail "Can't run to main"
400 return
401 }
402
403 # When using mi_expect_stop, we don't expect a prompt after the *stopped
404 # event, since the blocking commands are done from the CLI. Setting async
405 # to 1 makes it not expect the prompt.
406 set async 1
407
408 with_spawn_id $gdb_main_spawn_id {
409 # Add the second inferior now. While this is not mandatory, it allows
410 # us to assume that per-inferior thread numbering will be used,
411 # simplifying test_continue_to_start a bit (Thread 1.2 and not Thread 2).
412 gdb_test "add-inferior" "Added inferior 2" "Add inferior 2"
413
414 # Prepare the first inferior for the test.
415 test_continue_to_start $mode 1
416
417 # Switch to and start the second inferior.
418 gdb_test "inferior 2" "\\\[Switching to inferior 2${any}\\\]" "switch to inferior 2"
419 gdb_load ${binfile}
420
421 # Doing "start" on the CLI generates a ton of MI output. At some point,
422 # if we don't consume/match it, the buffer between GDB's MI channel and
423 # Expect will get full, GDB will block on a write system call and we'll
424 # deadlock, waiting for CLI output that will never arrive. And then
425 # we're sad. So instead of using gdb_test and expect CLI output, send
426 # the start command first, then consume MI output, and finally consume
427 # CLI output.
428 send_gdb "start\n"
429
430 with_spawn_id $mi_spawn_id {
431 mi_expect_stop "breakpoint-hit" "main" "" "$srcfile" "$decimal" \
432 {"" "disp=\"del\""} "main stop"
433 }
434
435 # Consume CLI output.
436 gdb_test "" "Temporary breakpoint.*Starting program.*"
437
438 # Prepare the second inferior for the test.
439 test_continue_to_start $mode 2
440 }
441 }
442
443 # Reset the selection to frame #0 of thread THREAD.
444
445 proc reset_selection { thread } {
446 global gdb_main_spawn_id
447
448 set any "\[^\r\n\]*"
449
450 with_spawn_id $gdb_main_spawn_id {
451 gdb_test "thread $thread" \
452 "\\\[Switching to thread $thread ${any}\\\].*" \
453 "reset selection to thread $thread"
454 gdb_test "frame 0" ".*" "reset selection to frame 0"
455 }
456 }
457
458 # Flush Expect's internal buffers for both CLI and MI.
459 #
460 # The idea here is to send a command, and to consume all the characters that we
461 # expect that command to output, including the following prompt. Using gdb_test
462 # and mi_gdb_test should do that.
463
464 proc flush_buffers { } {
465 global gdb_main_spawn_id mi_spawn_id
466
467 with_spawn_id $gdb_main_spawn_id {
468 gdb_test "print 444" "= 444" "flush CLI"
469 }
470
471 with_spawn_id $mi_spawn_id {
472 mi_gdb_test "555-data-evaluate-expression 666" ".*done,value=\"666\"" "flush MI"
473 }
474 }
475
476 # Run a command on the current spawn id, to confirm that no output is pending
477 # in Expect's internal buffer. This is used to ensure that nothing was output
478 # on the spawn id since the call to gdb_test/mi_gdb_test/flush_buffers.
479 #
480 # The key here is that the regexes use start-of-buffer anchors (^), ensuring
481 # that they match the entire buffer, confirming that there was nothing in it
482 # before.
483
484 proc ensure_no_output { test } {
485 global gdb_spawn_id gdb_main_spawn_id mi_spawn_id
486 global decimal
487
488 if { $gdb_spawn_id == $gdb_main_spawn_id } {
489 # CLI
490 gdb_test "print 666" \
491 "^print 666\r\n\\\$$decimal = 666" \
492 "$test, ensure no output CLI"
493 } elseif { $gdb_spawn_id == $mi_spawn_id } {
494 # MI
495 mi_gdb_test "777-data-evaluate-expression 888" \
496 "^777-data-evaluate-expression 888\r\n777\\^done,value=\"888\"" \
497 "$test, ensure no output MI"
498 } else {
499 error "Unexpected gdb_spawn_id value."
500 }
501 }
502
503 # Match a regular expression, or ensure that there was no output.
504 #
505 # If RE is non-empty, try to match the content of the program output (using the
506 # current spawn_id) and pass/fail TEST accordingly.
507 # If RE is empty, ensure that the program did not output anything.
508
509 proc match_re_or_ensure_not_output { re test } {
510 if { $re != "" } {
511 gdb_expect {
512 -re "$re" {
513 pass $test
514 }
515
516 default {
517 fail $test
518 }
519 }
520 } else {
521 ensure_no_output $test
522 }
523 }
524
525 # Test selecting an inferior from CLI.
526
527 proc_with_prefix test_cli_inferior { mode } {
528 global gdb_main_spawn_id mi_spawn_id
529
530 reset_selection "1.1"
531
532 set mi_re [make_mi_re $mode 4 2 event]
533 set cli_re [make_cli_re $mode 2 2.1 2]
534
535 flush_buffers
536
537 # Do the 'inferior' command.
538 with_spawn_id $gdb_main_spawn_id {
539 gdb_test "inferior 2" $cli_re "CLI select inferior"
540 }
541
542 with_spawn_id $mi_spawn_id {
543 match_re_or_ensure_not_output $mi_re "event on MI"
544 }
545
546 # Do the 'inferior' command on the currently selected inferior. For now,
547 # GDB naively re-outputs everything.
548 with_spawn_id $gdb_main_spawn_id {
549 gdb_test "inferior 2" $cli_re "CLI select inferior again"
550 }
551
552 with_spawn_id $mi_spawn_id {
553 match_re_or_ensure_not_output $mi_re "event on MI again"
554 }
555 }
556
557 # Test thread selection from CLI.
558
559 proc_with_prefix test_cli_thread { mode } {
560 global gdb_main_spawn_id
561 global mi_spawn_id
562
563 set any "\[^\r\n\]*"
564
565 reset_selection "1.1"
566 flush_buffers
567
568 with_test_prefix "thread 1.2" {
569 # Do the 'thread' command to select a stopped thread.
570
571 set mi_re [make_mi_re $mode 2 0 event]
572 set cli_re [make_cli_re $mode -1 1.2 0]
573
574 with_spawn_id $gdb_main_spawn_id {
575 gdb_test "thread 1.2" $cli_re "select thread"
576 }
577
578 with_spawn_id $mi_spawn_id {
579 match_re_or_ensure_not_output $mi_re "select thread, event on MI "
580 }
581
582 # Do the 'thread' command to select the same thread. We shouldn't receive
583 # an event on MI, since we won't actually switch thread.
584
585 set mi_re ""
586
587 with_spawn_id $gdb_main_spawn_id {
588 gdb_test "thread 1.2" $cli_re "select thread again"
589 }
590
591 with_spawn_id $mi_spawn_id {
592 match_re_or_ensure_not_output $mi_re "select thread, event on MI again"
593 }
594
595 # Try the 'thread' command without arguments.
596
597 set cli_re "\\\[Current thread is 1\\.2.*\\\]"
598 set mi_re ""
599
600 with_spawn_id $gdb_main_spawn_id {
601 gdb_test "thread" $cli_re "thread without args"
602 }
603
604 with_spawn_id $mi_spawn_id {
605 match_re_or_ensure_not_output $mi_re "thread without args, event on MI"
606 }
607 }
608
609 with_test_prefix "thread 1.3" {
610 # Do the 'thread' command to select the third thread, stopped on all-stop,
611 # running on non-stop.
612
613 if { $mode == "all-stop" } {
614 set cli_re [make_cli_re $mode -1 1.3 0]
615 set mi_re [make_mi_re $mode 3 0 event]
616 } else {
617 set cli_re [make_cli_re $mode -1 1.3 -1]
618 set mi_re [make_mi_re $mode 3 -1 event]
619 }
620
621 with_spawn_id $gdb_main_spawn_id {
622 gdb_test "thread 1.3" $cli_re "select thread"
623 }
624
625 with_spawn_id $mi_spawn_id {
626 match_re_or_ensure_not_output $mi_re "select thread, event on MI"
627 }
628
629 # Do the 'thread' command to select the third thread again. Again, we
630 # shouldn't receive an event on MI.
631
632 set mi_re ""
633
634 with_spawn_id $gdb_main_spawn_id {
635 gdb_test "thread 1.3" $cli_re "select thread again"
636 }
637
638 with_spawn_id $mi_spawn_id {
639 match_re_or_ensure_not_output $mi_re "select thread again, event on MI"
640 }
641
642 # Try the 'thread' command without arguments.
643
644 set cli_re "\\\[Current thread is 1\\.3 ${any}\\\]"
645 set mi_re ""
646
647 with_spawn_id $gdb_main_spawn_id {
648 gdb_test "thread" $cli_re "thread without args"
649 }
650
651 with_spawn_id $mi_spawn_id {
652 match_re_or_ensure_not_output $mi_re "thread without args, event on MI"
653 }
654 }
655
656 # Idea for the future: selecting a thread in a different inferior. For now,
657 # GDB doesn't show an inferior switch, but if it did, it would be a nice
658 # place to test it.
659 }
660
661 # Test frame selection from CLI.
662
663 proc_with_prefix test_cli_frame { mode } {
664 global gdb_main_spawn_id mi_spawn_id
665
666 with_test_prefix "thread 1.2" {
667 reset_selection "1.2"
668 flush_buffers
669
670 # Do the 'frame' command to select frame 1.
671
672 set mi_re [make_mi_re $mode 2 1 event]
673 set cli_re [make_cli_re $mode -1 -1 1]
674
675 with_spawn_id $gdb_main_spawn_id {
676 gdb_test "frame 1" $cli_re "select frame 1"
677 }
678
679 with_spawn_id $mi_spawn_id {
680 match_re_or_ensure_not_output $mi_re "select frame 1, event on MI"
681 }
682
683 # Do the 'frame' command to select the same frame. This time we don't
684 # expect an event on MI, since we won't actually change frame.
685
686 set mi_re ""
687
688 with_spawn_id $gdb_main_spawn_id {
689 gdb_test "frame 1" $cli_re "select frame 1 again"
690 }
691
692 with_spawn_id $mi_spawn_id {
693 match_re_or_ensure_not_output $mi_re "select frame 1 again, event on MI"
694 }
695
696 # Do the 'frame' command without arguments. We shouldn't see anything on MI.
697
698 with_spawn_id $gdb_main_spawn_id {
699 gdb_test "frame" $cli_re "frame without args"
700 }
701
702 with_spawn_id $mi_spawn_id {
703 match_re_or_ensure_not_output $mi_re "frame without args, event on MI"
704 }
705 }
706
707 with_test_prefix "thread 1.3" {
708 # Now, try the 'frame' command on thread 3, which is running if we are in
709 # non-stop mode.
710 reset_selection "1.3"
711 flush_buffers
712
713 if {$mode == "all-stop"} {
714 set mi_re [make_mi_re $mode 3 1 event]
715 set cli_re [make_cli_re $mode -1 -1 1]
716 } elseif {$mode == "non-stop"} {
717 set mi_re ""
718 set cli_re "Selected thread is running\\."
719 }
720
721 with_spawn_id $gdb_main_spawn_id {
722 gdb_test "frame 1" $cli_re "select frame 1"
723 }
724
725 with_spawn_id $mi_spawn_id {
726 match_re_or_ensure_not_output $mi_re "select frame 1, event on MI"
727 }
728
729 # Do the 'frame' command without arguments.
730
731 if { $mode == "non-stop" } {
732 set cli_re "No stack\\."
733 }
734 set mi_re ""
735
736 with_spawn_id $gdb_main_spawn_id {
737 gdb_test "frame" $cli_re "frame without args"
738 }
739
740 with_spawn_id $mi_spawn_id {
741 match_re_or_ensure_not_output $mi_re "frame without args, event on MI"
742 }
743 }
744 }
745
746 # Test frame selection from CLI with the select-frame command.
747
748 proc_with_prefix test_cli_select_frame { mode } {
749 global gdb_main_spawn_id mi_spawn_id expect_out
750
751 with_test_prefix "thread 1.2" {
752 reset_selection "1.2"
753 flush_buffers
754
755 # Do the 'select-frame' command to select frame 1.
756
757 set mi_re [make_mi_re $mode 2 1 event]
758
759 with_spawn_id $gdb_main_spawn_id {
760 gdb_test_no_output "select-frame 1" "select frame 1"
761 }
762
763 with_spawn_id $mi_spawn_id {
764 match_re_or_ensure_not_output $mi_re "select frame 1, event on MI"
765 }
766
767 # Do the 'select-frame' command to select the same frame. This time we expect to
768 # event on MI, since we won't actually change frame.
769
770 set mi_re ""
771
772 with_spawn_id $gdb_main_spawn_id {
773 gdb_test_no_output "select-frame 1" "select frame 1 again"
774 }
775
776 with_spawn_id $mi_spawn_id {
777 match_re_or_ensure_not_output $mi_re "select frame 1 again, event on MI"
778 }
779 }
780
781 with_test_prefix "thread 1.3" {
782 # Now, try the 'select-frame' command on thread 3, which is running if we are in
783 # non-stop mode.
784 reset_selection "1.3"
785 flush_buffers
786
787 if {$mode == "all-stop"} {
788 set mi_re [make_mi_re $mode 3 1 event]
789 } elseif {$mode == "non-stop"} {
790 set mi-re ""
791 set cli_re "Selected thread is running\\."
792 }
793
794 with_spawn_id $gdb_main_spawn_id {
795 if { $mode == "all-stop" } {
796 gdb_test_no_output "select-frame 1" "select frame 1"
797 } else {
798 gdb_test "select-frame 1" $cli_re "select frame 1"
799 }
800 }
801
802 with_spawn_id $mi_spawn_id {
803 match_re_or_ensure_not_output $mi_re "select frame 1, event on MI"
804 }
805 }
806 }
807
808 # Test doing an up and then down command from CLI.
809
810 proc_with_prefix test_cli_up_down { mode } {
811 global gdb_main_spawn_id mi_spawn_id
812
813 reset_selection "1.2"
814 flush_buffers
815
816 # Try doing an 'up'.
817
818 set mi_re [make_mi_re $mode 2 1 event]
819 set cli_re [make_cli_re $mode -1 -1 1]
820
821 with_spawn_id $gdb_main_spawn_id {
822 gdb_test "up" $cli_re "frame up"
823 }
824
825 with_spawn_id $mi_spawn_id {
826 match_re_or_ensure_not_output $mi_re "frame up, event on MI"
827 }
828
829 # Try doing a 'down'.
830
831 set mi_re [make_mi_re $mode 2 0 event]
832 set cli_re [make_cli_re $mode -1 -1 0]
833
834 with_spawn_id $gdb_main_spawn_id {
835 gdb_test "down" $cli_re "frame down"
836 }
837
838 with_spawn_id $mi_spawn_id {
839 match_re_or_ensure_not_output $mi_re "frame down, event on MI"
840 }
841 }
842
843 # Test selecting a thread from MI.
844
845 proc_with_prefix test_mi_thread_select { mode } {
846 global gdb_main_spawn_id mi_spawn_id
847
848 reset_selection "1.1"
849 flush_buffers
850
851 with_test_prefix "thread 1.2" {
852 # Do the '-thread-select' command to select a stopped thread.
853
854 set mi_re [make_mi_re $mode 2 0 response]
855 set cli_re [make_cli_re $mode -1 1.2 0]
856
857 with_spawn_id $mi_spawn_id {
858 mi_gdb_test "-thread-select 2" $mi_re "-thread-select"
859 }
860
861 with_spawn_id $gdb_main_spawn_id {
862 match_re_or_ensure_not_output "$cli_re\r\n" "-thread-select, event on CLI"
863 }
864
865 # Do the '-thread-select' command to select the same thread. We
866 # shouldn't receive an event on CLI, since we won't actually switch
867 # thread.
868
869 set cli_re ""
870
871 with_spawn_id $mi_spawn_id {
872 mi_gdb_test "-thread-select 2" $mi_re "-thread-select again"
873 }
874
875 with_spawn_id $gdb_main_spawn_id {
876 match_re_or_ensure_not_output $cli_re "-thread-select again, event on CLI"
877 }
878 }
879
880 with_test_prefix "thread 1.3" {
881 # Do the '-thread-select' command to select the third thread, stopped on all-stop,
882 # running on non-stop.
883
884 if { $mode == "all-stop" } {
885 set mi_re [make_mi_re $mode 3 0 response]
886 set cli_re [make_cli_re $mode -1 1.3 0]
887 } else {
888 set mi_re [make_mi_re $mode 3 -1 response]
889 set cli_re [make_cli_re $mode -1 1.3 -1]
890 }
891
892 with_spawn_id $mi_spawn_id {
893 mi_gdb_test "-thread-select 3" $mi_re "-thread-select"
894 }
895
896 with_spawn_id $gdb_main_spawn_id {
897 match_re_or_ensure_not_output "$cli_re\r\n" "-thread-select, event on CLI"
898 }
899
900 # Do the 'thread' command to select the third thread again. Again, we
901 # shouldn't receive an event on MI.
902
903 set cli_re ""
904
905 with_spawn_id $mi_spawn_id {
906 mi_gdb_test "-thread-select 3" $mi_re "-thread-select again"
907 }
908
909 with_spawn_id $gdb_main_spawn_id {
910 match_re_or_ensure_not_output $cli_re "-thread-select again, event on CLI"
911 }
912 }
913
914 with_test_prefix "thread 1.2 with --thread" {
915 # Test selecting a thread from MI with a --thread option. This test
916 # verifies that even if the thread GDB would switch to is the same has
917 # the thread specified with --thread, an event is still sent to CLI.
918 # In this case this is thread 1.2
919
920 set mi_re [make_mi_re $mode 2 0 response]
921 set cli_re [make_cli_re $mode -1 1.2 0]
922
923 with_spawn_id $mi_spawn_id {
924 mi_gdb_test "-thread-select --thread 2 2" $mi_re "-thread-select"
925 }
926
927 with_spawn_id $gdb_main_spawn_id {
928 # This doesn't work as of now, no event is sent on CLI. It is
929 # commented out so we don't have to wait for the timeout every time.
930 # match_re_or_ensure_not_output "$cli_re\r\n" "-thread-select, event on cli"
931 kfail "gdb/20631" "thread-select, event on cli"
932 }
933 }
934
935 # Idea for the future: selecting a thread in a different inferior. For now,
936 # GDB doesn't show an inferior switch, but if it did, it would be a nice
937 # place to test it.
938 }
939
940 proc_with_prefix test_mi_stack_select_frame { mode } {
941 global gdb_main_spawn_id mi_spawn_id
942
943 with_test_prefix "thread 1.2" {
944 reset_selection "1.2"
945 flush_buffers
946
947 # Do the '-stack-select-frame' command to select frame 1.
948
949 set mi_re "\\^done"
950 set cli_re [make_cli_re $mode -1 -1 1]
951
952 with_spawn_id $mi_spawn_id {
953 mi_gdb_test "-stack-select-frame 1" $mi_re "-stack-select-frame"
954 }
955
956 with_spawn_id $gdb_main_spawn_id {
957 match_re_or_ensure_not_output "$cli_re\r\n" "-stack-select-frame, event on MI"
958 }
959
960 # Do the '-stack-select-frame' command to select the same frame. This time we don't
961 # expect an event on CLI, since we won't actually change frame.
962
963 set cli_re ""
964
965 with_spawn_id $mi_spawn_id {
966 mi_gdb_test "-stack-select-frame 1" $mi_re "-stack-select-frame again"
967 }
968
969 with_spawn_id $gdb_main_spawn_id {
970 match_re_or_ensure_not_output $cli_re "-stack-select-frame again, event on MI"
971 }
972 }
973
974 with_test_prefix "thread 1.3" {
975 # Now, try the '-stack-select-frame' command on thread 3, which is
976 # running if we are in non-stop mode.
977 reset_selection "1.3"
978 flush_buffers
979
980 if {$mode == "all-stop"} {
981 set mi_re "\\^done"
982 set cli_re [make_cli_re $mode -1 -1 1]
983 append cli_re "\r\n"
984 } elseif {$mode == "non-stop"} {
985 set cli_re ""
986 set mi_re "\\^error,msg=\"Selected thread is running\\.\""
987 }
988
989 with_spawn_id $mi_spawn_id {
990 mi_gdb_test "-stack-select-frame 1" $mi_re "-stack-select-frame"
991 }
992
993 with_spawn_id $gdb_main_spawn_id {
994 match_re_or_ensure_not_output $cli_re "-stack-select-frame, event on MI"
995 }
996 }
997 }
998
999 proc make_cli_in_mi_command { cli_in_mi_mode command } {
1000 if { $cli_in_mi_mode == "direct" } {
1001 return $command
1002 } elseif { $cli_in_mi_mode == "interpreter-exec" } {
1003 return "-interpreter-exec console \"$command\""
1004 } else {
1005 error "Invalid value for CLI_IN_MI_MODE."
1006 }
1007 }
1008
1009 # Test selecting the inferior using a CLI command in the MI channel.
1010
1011 proc_with_prefix test_cli_in_mi_inferior { mode cli_in_mi_mode } {
1012 global gdb_main_spawn_id mi_spawn_id
1013
1014 reset_selection "1.1"
1015 flush_buffers
1016
1017 set command [make_cli_in_mi_command $cli_in_mi_mode "inferior 2"]
1018
1019 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 2 2.1 4 2]
1020 set cli_re [make_cli_re $mode 2 "2.1" 2]
1021
1022 with_spawn_id $mi_spawn_id {
1023 mi_gdb_test $command $mi_re "select inferior"
1024 }
1025
1026 with_spawn_id $gdb_main_spawn_id {
1027 match_re_or_ensure_not_output "$cli_re\r\n" "select inferior, event on CLI"
1028 }
1029
1030 # Do the 'inferior' command on the currently selected inferior. For now,
1031 # GDB naively re-outputs everything.
1032 with_spawn_id $mi_spawn_id {
1033 mi_gdb_test $command $mi_re "select inferior again"
1034 }
1035
1036 with_spawn_id $gdb_main_spawn_id {
1037 match_re_or_ensure_not_output $cli_re "select inferior again, event on CLI"
1038 }
1039 }
1040
1041 # Test selecting the thread using a CLI command in the MI channel.
1042
1043 proc_with_prefix test_cli_in_mi_thread { mode cli_in_mi_mode } {
1044 global gdb_main_spawn_id mi_spawn_id
1045
1046 reset_selection "1.1"
1047 flush_buffers
1048
1049 with_test_prefix "thread 1.2" {
1050 # Do the 'thread' command to select a stopped thread.
1051
1052 set command [make_cli_in_mi_command $cli_in_mi_mode "thread 1.2"]
1053 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 -1 1.2 2 0]
1054 set cli_re [make_cli_re $mode -1 1.2 0]
1055
1056 with_spawn_id $mi_spawn_id {
1057 mi_gdb_test $command $mi_re "select thread"
1058 }
1059
1060 with_spawn_id $gdb_main_spawn_id {
1061 match_re_or_ensure_not_output "$cli_re\r\n" "select thread, event on CLI"
1062 }
1063
1064 # Do the 'thread' command to select the same thread. We shouldn't
1065 # receive an event on CLI, since we won't actually switch thread.
1066
1067 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 1.2 2 0]
1068 set cli_re ""
1069
1070 with_spawn_id $mi_spawn_id {
1071 mi_gdb_test $command $mi_re "select thread again"
1072 }
1073
1074 with_spawn_id $gdb_main_spawn_id {
1075 match_re_or_ensure_not_output $cli_re "select thread again, event on CLI"
1076 }
1077
1078 # Try the 'thread' command without arguments.
1079
1080 set command [make_cli_in_mi_command $cli_in_mi_mode "thread"]
1081
1082 set mi_re "${command}.*~\"\\\[Current thread is 1\\.2.*\\\]\\\\n\".*\\^done"
1083 set cli_re ""
1084
1085 with_spawn_id $mi_spawn_id {
1086 mi_gdb_test $command $mi_re "thread without args"
1087 }
1088
1089 with_spawn_id $gdb_main_spawn_id {
1090 match_re_or_ensure_not_output $cli_re "thread without args, event on CLI"
1091 }
1092 }
1093
1094 with_test_prefix "thread 1.3" {
1095 # Do the 'thread' command to select the third thread, stopped on
1096 # all-stop, running on non-stop.
1097
1098 set command [make_cli_in_mi_command $cli_in_mi_mode "thread 1.3"]
1099 if { $mode == "all-stop" } {
1100 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 -1 1.3 3 0]
1101 set cli_re [make_cli_re $mode -1 "1.3" 0]
1102 } else {
1103 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 -1 1.3 3 -1]
1104 set cli_re [make_cli_re $mode -1 "1.3" -1]
1105 }
1106
1107 with_spawn_id $mi_spawn_id {
1108 mi_gdb_test $command $mi_re "select thread"
1109 }
1110
1111 with_spawn_id $gdb_main_spawn_id {
1112 match_re_or_ensure_not_output "$cli_re\r\n" "select thread, event on CLI"
1113 }
1114
1115 # Do the 'thread' command to select the third thread again. Again, we
1116 # shouldn't receive an event on MI.
1117
1118 if { $mode == "all-stop" } {
1119 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 1.3 3 0]
1120 } else {
1121 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 1.3 3 -1]
1122 }
1123 set cli_re ""
1124
1125 with_spawn_id $mi_spawn_id {
1126 mi_gdb_test $command $mi_re "select thread again"
1127 }
1128
1129 with_spawn_id $gdb_main_spawn_id {
1130 match_re_or_ensure_not_output $cli_re "select thread again, event on CLI"
1131 }
1132
1133 # Try the 'thread' command without arguments.
1134
1135 set command [make_cli_in_mi_command $cli_in_mi_mode "thread"]
1136
1137 set mi_re "${command}.*~\"\\\[Current thread is 1\\.3.*\\\]\\\\n\".*\\^done"
1138 set cli_re ""
1139
1140 with_spawn_id $mi_spawn_id {
1141 mi_gdb_test $command $mi_re "thread without args"
1142 }
1143
1144 with_spawn_id $gdb_main_spawn_id {
1145 match_re_or_ensure_not_output $cli_re "thread without args, event on CLI"
1146 }
1147 }
1148
1149 # Idea for the future: selecting a thread in a different inferior. For now,
1150 # GDB doesn't show an inferior switch, but if it did, it would be a nice
1151 # place to test it.
1152 }
1153
1154 # Test selecting the frame using a CLI command in the MI channel.
1155
1156 proc_with_prefix test_cli_in_mi_frame { mode cli_in_mi_mode } {
1157 global gdb_main_spawn_id mi_spawn_id
1158
1159 with_test_prefix "thread 1.2" {
1160 reset_selection "1.2"
1161 flush_buffers
1162
1163 # Do the 'frame' command to select frame 1.
1164
1165 set command [make_cli_in_mi_command $cli_in_mi_mode "frame 1"]
1166 set cli_re [make_cli_re $mode -1 -1 1]
1167 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 -1 -1 2 1]
1168
1169 with_spawn_id $mi_spawn_id {
1170 mi_gdb_test $command $mi_re "select frame 1"
1171 }
1172
1173 with_spawn_id $gdb_main_spawn_id {
1174 match_re_or_ensure_not_output "$cli_re\r\n" "select frame 1, event on CLI"
1175 }
1176
1177 # Do the 'frame' command to select the same frame. This time we don't
1178 # expect an event on MI, since we won't actually change frame.
1179
1180 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 -1 2 1]
1181 set cli_re ""
1182
1183 with_spawn_id $mi_spawn_id {
1184 mi_gdb_test $command $mi_re "select frame 1 again"
1185 }
1186
1187 with_spawn_id $gdb_main_spawn_id {
1188 match_re_or_ensure_not_output $cli_re "select frame 1 again, event on CLI"
1189 }
1190
1191 # Do the 'frame' command without arguments. We shouldn't see anything on MI.
1192
1193 set command [make_cli_in_mi_command $cli_in_mi_mode "frame"]
1194 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 -1 2 1]
1195
1196 with_spawn_id $mi_spawn_id {
1197 mi_gdb_test $command $mi_re "frame without args"
1198 }
1199
1200 with_spawn_id $gdb_main_spawn_id {
1201 match_re_or_ensure_not_output $cli_re "frame without args, event on CLI"
1202 }
1203 }
1204
1205 with_test_prefix "thread 1.3" {
1206 # Now, try the 'frame' command on thread 3, which is running if we are in
1207 # non-stop mode.
1208 reset_selection "1.3"
1209 flush_buffers
1210
1211 set command [make_cli_in_mi_command $cli_in_mi_mode "frame 1"]
1212 if {$mode == "all-stop"} {
1213 set cli_re [make_cli_re $mode -1 -1 1]
1214 append cli_re "\r\n"
1215 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 -1 -1 3 1]
1216 } elseif {$mode == "non-stop"} {
1217 set cli_re ""
1218 set mi_re "\\^error,msg=\"Selected thread is running\\.\".*"
1219 }
1220
1221 with_spawn_id $mi_spawn_id {
1222 mi_gdb_test $command $mi_re "select frame 1"
1223 }
1224
1225 with_spawn_id $gdb_main_spawn_id {
1226 match_re_or_ensure_not_output $cli_re "select frame 1, event on CLI"
1227 }
1228
1229 # Do the 'frame' command without arguments.
1230
1231 set command [make_cli_in_mi_command $cli_in_mi_mode "frame"]
1232 if { $mode == "all-stop" } {
1233 set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 0 -1 -1 -1 1]
1234 } else {
1235 set mi_re "\\^error,msg=\"No stack\\.\""
1236 }
1237 set cli_re ""
1238
1239 with_spawn_id $mi_spawn_id {
1240 mi_gdb_test $command $mi_re "frame without args"
1241 }
1242
1243 with_spawn_id $gdb_main_spawn_id {
1244 match_re_or_ensure_not_output $cli_re "frame without args, event on CLI"
1245 }
1246 }
1247 }
1248
1249 foreach_with_prefix mode { "all-stop" "non-stop" } {
1250 test_setup $mode
1251
1252 # Test selecting inferior, thread and frame from CLI
1253
1254 test_cli_inferior $mode
1255 test_cli_thread $mode
1256 test_cli_frame $mode
1257 test_cli_select_frame $mode
1258 test_cli_up_down $mode
1259
1260 # Test selecting thread and frame from MI
1261
1262 test_mi_thread_select $mode
1263 test_mi_stack_select_frame $mode
1264
1265 # Test some CLI commands sent through MI, both with a "direct" command,
1266 # such as "thread 1", and with -interpreter-exec, such as
1267 # '-interpreter-exec console "thread 1"'.
1268
1269 foreach_with_prefix exec_mode {"direct" "interpreter-exec"} {
1270 test_cli_in_mi_inferior $mode $exec_mode
1271 test_cli_in_mi_thread $mode $exec_mode
1272 test_cli_in_mi_frame $mode $exec_mode
1273 }
1274 }
This page took 0.058054 seconds and 5 git commands to generate.