]>
Commit | Line | Data |
---|---|---|
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 | 18 | require allow_dap_tests |
8900a92e TT |
19 | |
20 | load_lib dap-support.exp | |
21 | ||
22 | standard_testfile | |
23 | ||
24 | if {[build_executable ${testfile}.exp $testfile] == -1} { | |
25 | return | |
26 | } | |
27 | ||
28 | if {[dap_launch $testfile] == ""} { | |
29 | return | |
30 | } | |
31 | ||
32 | set line [gdb_get_line_number "BREAK"] | |
33 | set 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]] | |
37 | set line_bpno [dap_get_breakpoint_number $obj] | |
38 | ||
39 | dap_check_request_and_response "start inferior" configurationDone | |
40 | dap_wait_for_event_and_check "inferior started" thread "body reason" started | |
41 | ||
42 | dap_wait_for_event_and_check "stopped at line breakpoint" stopped \ | |
43 | "body reason" breakpoint \ | |
44 | "body hitBreakpointIds" $line_bpno | |
45 | ||
46 | set bt [lindex [dap_check_request_and_response "backtrace" stackTrace \ | |
47 | {o threadId [i 1]}] \ | |
48 | 0] | |
49 | set frame_id [dict get [lindex [dict get $bt body stackFrames] 0] id] | |
50 | ||
51 | set scopes [dap_check_request_and_response "get scopes" scopes \ | |
52 | [format {o frameId [i %d]} $frame_id]] | |
53 | set 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. | |
57 | set scopes2 [dap_check_request_and_response "get scopes again" scopes \ | |
58 | [format {o frameId [i %d]} $frame_id]] | |
59 | set scopes2 [dict get [lindex $scopes2 0] body scopes] | |
60 | gdb_assert {$scopes2 == $scopes} "identical scopes requests yield same body" | |
61 | ||
14e8fded | 62 | gdb_assert {[llength $scopes] == 2} "two scopes" |
8900a92e | 63 | |
14e8fded | 64 | lassign $scopes scope reg_scope |
8900a92e | 65 | gdb_assert {[dict get $scope name] == "Locals"} "scope is locals" |
14e8fded TT |
66 | gdb_assert {[dict get $scope presentationHint] == "locals"} \ |
67 | "locals presentation hint" | |
8900a92e TT |
68 | gdb_assert {[dict get $scope namedVariables] == 3} "three vars in scope" |
69 | ||
14e8fded TT |
70 | gdb_assert {[dict get $reg_scope name] == "Registers"} \ |
71 | "second scope is registers" | |
72 | gdb_assert {[dict get $reg_scope presentationHint] == "registers"} \ | |
73 | "registers presentation hint" | |
74 | gdb_assert {[dict get $reg_scope namedVariables] > 0} "at least one register" | |
75 | ||
8900a92e | 76 | set num [dict get $scope variablesReference] |
59e75852 TT |
77 | # Send two requests and combine them, to verify that using a range |
78 | # works. | |
79 | set 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] | |
84 | set 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 | ||
91 | set vars [concat [dict get $refs1 body variables] \ | |
92 | [dict get $refs2 body variables]] | |
93 | foreach 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 | ||
119 | set refs [lindex [dap_check_request_and_response "fetch contents of dei" \ | |
120 | "variables" \ | |
121 | [format {o variablesReference [i %d]} $dei_ref]] \ | |
122 | 0] | |
123 | set deivals [dict get $refs body variables] | |
124 | gdb_assert {[llength $deivals] == 2} "dei has two members" | |
125 | ||
14e8fded TT |
126 | set num [dict get $reg_scope variablesReference] |
127 | # The request succeeding is sufficient. | |
138c7d26 TT |
128 | set 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. | |
133 | set val [dict get [lindex $val 0] body variables] | |
134 | set name [dict get [lindex $val 0] name] | |
135 | set val [dict get [lindex $val 0] value] | |
136 | # Just make sure it is different from the original value. | |
137 | set 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. | |
142 | set 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]] | |
146 | set response [lindex $response 0] | |
147 | ||
148 | gdb_assert {[dict get $response body value] == $val} \ | |
149 | "setting register yields updated value" | |
14e8fded | 150 | |
8900a92e | 151 | dap_shutdown |