1# Copyright 2022-2023 Free Software Foundation, Inc.
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16# Test that GDB/MI commands preserve user selected context when
17# passed --thread and/or --frame.
18
19load_lib mi-support.exp
20
21standard_testfile
22
23if {[build_executable $testfile.exp $testfile ${srcfile} "debug pthreads"] == -1} {
24    untested "failed to compile"
25    return -1
26}
27
28set main_break_line [gdb_get_line_number "main break line"]
29
30set any "\[^\r\n\]*"
31
32mi_clean_restart $binfile
33mi_create_breakpoint "$srcfile:$main_break_line" "set breakpoint in main"
34mi_run_cmd
35mi_expect_stop "breakpoint-hit" "main" "" $srcfile $main_break_line \
36	 { "" "disp=\"keep\"" } "run to breakpoint in main"
37
38mi_gdb_test "thread" \
39	".*Current thread is 1.*" \
40	"info thread 1"
41
42# Run -stack-info-depth in a different thread, the current thread
43# should not change.
44
45mi_gdb_test "-stack-info-depth --thread 3" \
46    "\\^done,depth=.*" \
47    "-stack-info-depth --thread 3"
48
49mi_gdb_test "thread" \
50    ".*Current thread is 1.*" \
51    "info thread 2"
52
53# Expect GDB to switch to thread 3.
54mi_gdb_test "-thread-select 3" \
55    "\\^done,${any}new-thread-id=\"3\"${any}" \
56    "-thread-select 3"
57
58mi_gdb_test "thread" \
59    ".*Current thread is 3.*" \
60    "info thread 3"
61
62# Expect GDB to switch to thread 1.
63mi_gdb_test "-thread-select --thread 2 1" \
64    "\\^done,${any}new-thread-id=\"1\"${any}" \
65    "-thread-select --thread 2 1"
66
67mi_gdb_test "thread" \
68    ".*Current thread is 1.*" \
69    "info thread 4"
70
71# Expect GDB to switch to thread 2.
72mi_gdb_test "-thread-select --thread 2 2" \
73    "\\^done,.*" \
74    "-thread-select --thread 2 2"
75
76mi_gdb_test "thread" \
77    ".*Current thread is 2.*" \
78    "info thread 5"
79
80# Check we're in frame 0.
81mi_gdb_test "frame" \
82    ".*#0  .*child_sub_function .*" \
83    "frame 1"
84
85# Ask about a different frame in the current thread, the current frame
86# should not change.
87mi_gdb_test "-stack-info-frame --thread 2 --frame 1" \
88    "\\^done,frame=\{level=\"1\".*" \
89    "-stack-info-frame 1"
90
91mi_gdb_test "thread" \
92    ".*Current thread is 2.*" \
93    "info thread 6"
94
95mi_gdb_test "frame" \
96    ".*#0  .*child_sub_function.*" \
97    "frame 2"
98
99
100# Ask about a different frame in a different thread.  After this the
101# current thread and frame should not have changed.
102mi_gdb_test "-stack-info-frame --thread 3 --frame 1" \
103    "\\^done,frame=\{level=\"1\".*" \
104    "-stack-info-frame 2"
105
106mi_gdb_test "thread" \
107    ".*Current thread is 2.*" \
108    "info thread 7"
109
110mi_gdb_test "frame" \
111    ".*#0  .*child_sub_function.*" \
112    "frame 3"
113
114# Select a different frame in the current thread.  Despite the use of
115# the --frame option, we do expect the currently selected frame to
116# change.
117mi_gdb_test "-stack-select-frame --thread 2 --frame 0 1" \
118    "\\^done" \
119    "--stack-select-frame 1"
120
121mi_gdb_test "thread" \
122    ".*Current thread is 2.*" \
123    "info thread 8"
124
125mi_gdb_test "frame" \
126    ".*#1  .*child_function.*" \
127    "frame 4"
128
129# Similar to the previous test, but this time the --frame option is
130# the same as the frame we are selecting.  We still expect GDB to
131# update the currently selected frame.
132mi_gdb_test "-stack-select-frame --thread 2 --frame 2 2" \
133    "\\^done" \
134    "--stack-select-frame 2"
135
136mi_gdb_test "thread" \
137    ".*Current thread is 2.*" \
138    "info thread 9"
139
140mi_gdb_test "frame" \
141    ".*#2  0x.*" \
142    "frame 5"
143
144# Now select a frame in a different thread.  We expect both the
145# currently selected thread, and the currently selected frame to be
146# updated.
147mi_gdb_test "-stack-select-frame --thread 1 --frame 0 0" \
148    "\\^done" \
149    "--stack-select-frame 3"
150
151mi_gdb_test "thread" \
152    ".*Current thread is 1.*" \
153    "info thread 10"
154
155mi_gdb_test "frame" \
156    ".*#0  main.*" \
157    "frame 6"
158