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