]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/testsuite/gdb.dap/scopes.exp
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.dap / scopes.exp
CommitLineData
1d506c26 1# Copyright 2023-2024 Free Software Foundation, Inc.
8900a92e
TT
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 "scopes" and "variables".
17
95e592d9 18require allow_dap_tests
8900a92e
TT
19
20load_lib dap-support.exp
21
22standard_testfile
23
24if {[build_executable ${testfile}.exp $testfile] == -1} {
25 return
26}
27
28if {[dap_launch $testfile] == ""} {
29 return
30}
31
32set line [gdb_get_line_number "BREAK"]
33set obj [dap_check_request_and_response "set breakpoint by line number" \
34 setBreakpoints \
35 [format {o source [o path [%s]] breakpoints [a [o line [i %d]]]} \
36 [list s $srcfile] $line]]
37set line_bpno [dap_get_breakpoint_number $obj]
38
39dap_check_request_and_response "start inferior" configurationDone
40dap_wait_for_event_and_check "inferior started" thread "body reason" started
41
42dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
43 "body reason" breakpoint \
44 "body hitBreakpointIds" $line_bpno
45
46set bt [lindex [dap_check_request_and_response "backtrace" stackTrace \
47 {o threadId [i 1]}] \
48 0]
49set frame_id [dict get [lindex [dict get $bt body stackFrames] 0] id]
50
51set scopes [dap_check_request_and_response "get scopes" scopes \
52 [format {o frameId [i %d]} $frame_id]]
53set scopes [dict get [lindex $scopes 0] body scopes]
54
ed5504c7
TT
55# Request the scopes twice, and verify that the results are identical.
56# GDB previously had a bug where it would return new scopes each time.
57set scopes2 [dap_check_request_and_response "get scopes again" scopes \
58 [format {o frameId [i %d]} $frame_id]]
59set scopes2 [dict get [lindex $scopes2 0] body scopes]
60gdb_assert {$scopes2 == $scopes} "identical scopes requests yield same body"
61
14e8fded 62gdb_assert {[llength $scopes] == 2} "two scopes"
8900a92e 63
14e8fded 64lassign $scopes scope reg_scope
8900a92e 65gdb_assert {[dict get $scope name] == "Locals"} "scope is locals"
14e8fded
TT
66gdb_assert {[dict get $scope presentationHint] == "locals"} \
67 "locals presentation hint"
8900a92e
TT
68gdb_assert {[dict get $scope namedVariables] == 3} "three vars in scope"
69
14e8fded
TT
70gdb_assert {[dict get $reg_scope name] == "Registers"} \
71 "second scope is registers"
72gdb_assert {[dict get $reg_scope presentationHint] == "registers"} \
73 "registers presentation hint"
74gdb_assert {[dict get $reg_scope namedVariables] > 0} "at least one register"
75
8900a92e 76set num [dict get $scope variablesReference]
59e75852
TT
77# Send two requests and combine them, to verify that using a range
78# works.
79set refs1 [lindex [dap_check_request_and_response "fetch variables 0,1" \
80 "variables" \
81 [format {o variablesReference [i %d] count [i 2]} \
82 $num]] \
83 0]
84set refs2 [lindex [dap_check_request_and_response "fetch variables 2" \
85 "variables" \
86 [format {o variablesReference [i %d] \
87 start [i 2] count [i 1]} \
88 $num]] \
89 0]
90
91set vars [concat [dict get $refs1 body variables] \
92 [dict get $refs2 body variables]]
93foreach var $vars {
8900a92e
TT
94 set name [dict get $var name]
95
96 if {$name != "dei"} {
97 gdb_assert {[dict get $var variablesReference] == 0} \
98 "$name has no structure"
99 }
100
101 switch $name {
102 "inner" {
103 gdb_assert {[string match "*inner block*" [dict get $var value]]} \
104 "check value of inner"
105 }
106 "dei" {
107 gdb_assert {[dict get $var value] == ""} "check value of dei"
108 set dei_ref [dict get $var variablesReference]
109 }
110 "scalar" {
111 gdb_assert {[dict get $var value] == 23} "check value of scalar"
112 }
113 default {
114 fail "unknown variable $name"
115 }
116 }
117}
118
119set refs [lindex [dap_check_request_and_response "fetch contents of dei" \
120 "variables" \
121 [format {o variablesReference [i %d]} $dei_ref]] \
122 0]
123set deivals [dict get $refs body variables]
124gdb_assert {[llength $deivals] == 2} "dei has two members"
125
14e8fded
TT
126set num [dict get $reg_scope variablesReference]
127# The request succeeding is sufficient.
138c7d26
TT
128set val [dap_check_request_and_response "fetch first register" \
129 "variables" \
130 [format {o variablesReference [i %d] count [i 1]} $num]]
131
132# Try setting the value to something else.
133set val [dict get [lindex $val 0] body variables]
134set name [dict get [lindex $val 0] name]
135set val [dict get [lindex $val 0] value]
136# Just make sure it is different from the original value.
137set val [expr {$val ^ 7}]
138
139# setVariable isn't implemented yet, so use the register name. Note
140# that we sneak the "$" into the name, written in a slightly funny way
141# to work around apparent TON limitations.
142set response [dap_check_request_and_response "set first register" \
143 setExpression \
144 [format {o expression [s \$%s] value [s %d] frameId [i %d]} \
145 $name $val $frame_id]]
146set response [lindex $response 0]
147
148gdb_assert {[dict get $response body value] == $val} \
149 "setting register yields updated value"
14e8fded 150
8900a92e 151dap_shutdown