]>
Commit | Line | Data |
---|---|---|
14ade916 | 1 | # Copyright 2022-2023 Free Software Foundation, Inc. |
de7d7cb5 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 | # Basic DAP test. | |
17 | ||
95e592d9 | 18 | require allow_dap_tests |
d7201765 | 19 | |
de7d7cb5 TT |
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 obj [dap_check_request_and_response "set breakpoint on two functions" \ | |
33 | setFunctionBreakpoints \ | |
34 | {o breakpoints [a [o name [s function_breakpoint_here]] \ | |
35 | [o name [s do_not_stop_here]]]}] | |
36 | set fn_bpno [dap_get_breakpoint_number $obj] | |
37 | ||
38 | # This also tests that the previous do_not_stop_here breakpoint is | |
39 | # cleared. | |
40 | set obj [dap_check_request_and_response "set breakpoint on function" \ | |
41 | setFunctionBreakpoints \ | |
42 | {o breakpoints [a [o name [s function_breakpoint_here]]]}] | |
43 | set fn_bpno [dap_get_breakpoint_number $obj] | |
44 | ||
45 | set obj [dap_check_request_and_response "set breakpoint with invalid filename" \ | |
46 | setBreakpoints \ | |
47 | [format {o source [o path [s nosuchfilename.c]] breakpoints [a [o line [i 29]]]}]] | |
48 | ||
49 | set line [gdb_get_line_number "BREAK"] | |
50 | set obj [dap_check_request_and_response "set breakpoint by line number" \ | |
51 | setBreakpoints \ | |
52 | [format {o source [o path [%s]] breakpoints [a [o line [i %d]]]} \ | |
53 | [list s $srcfile] $line]] | |
54 | set line_bpno [dap_get_breakpoint_number $obj] | |
55 | ||
56 | # Check the new breakpoint event. | |
57 | set ok 0 | |
faee1372 | 58 | foreach d [lindex $obj 1] { |
de7d7cb5 TT |
59 | if {[dict get $d type] != "event" |
60 | || [dict get $d event] != "breakpoint"} { | |
61 | continue | |
62 | } | |
63 | if {[dict get $d body reason] == "new" | |
64 | && [dict get $d body breakpoint verified] == "true"} { | |
65 | set ok 1 | |
66 | pass "check new breakpoint event" | |
67 | break | |
68 | } | |
69 | } | |
70 | if {!$ok} { | |
71 | fail "check new breakpoint event" | |
72 | } | |
73 | ||
3c453cfb TT |
74 | # Check that there are breakpoint locations on each line between FIRST |
75 | # and BREAK. | |
76 | set first_line [gdb_get_line_number "FIRST"] | |
77 | set last_line [expr {$line - 1}] | |
78 | set obj [dap_check_request_and_response "breakpoint locations" \ | |
79 | breakpointLocations \ | |
80 | [format {o source [o path [%s]] line [i %d] endLine [i %d]} \ | |
81 | [list s $srcfile] $first_line $last_line]] | |
82 | # We know gdb returns the lines in sorted order. | |
83 | foreach entry [dict get [lindex $obj 0] body breakpoints] { | |
84 | gdb_assert {[dict get $entry line] == $first_line} \ | |
85 | "line $first_line in result" | |
86 | incr first_line | |
87 | } | |
88 | ||
de7d7cb5 TT |
89 | set obj [dap_check_request_and_response "reset breakpoint by line number" \ |
90 | setBreakpoints \ | |
91 | [format {o source [o path [%s]] breakpoints [a [o line [i %d]]]} \ | |
92 | [list s $srcfile] $line]] | |
93 | set new_line_bpno [dap_get_breakpoint_number $obj] | |
5dd4f358 | 94 | gdb_assert {$new_line_bpno == $line_bpno} "re-setting kept same breakpoint number" |
de7d7cb5 TT |
95 | |
96 | # This uses "&address_breakpoint_here" as the address -- this is a | |
97 | # hack because we know how this is implemented under the hood. | |
98 | set obj [dap_check_request_and_response "set breakpoint by address" \ | |
99 | setInstructionBreakpoints \ | |
100 | {o breakpoints [a [o instructionReference [s &address_breakpoint_here]]]}] | |
101 | set insn_bpno [dap_get_breakpoint_number $obj] | |
102 | ||
faee1372 SM |
103 | set response [lindex $obj 0] |
104 | set bplist [dict get $response body breakpoints] | |
de7d7cb5 TT |
105 | set insn_pc [dict get [lindex $bplist 0] instructionReference] |
106 | ||
107 | dap_check_request_and_response "start inferior" configurationDone | |
59db4c93 | 108 | dap_wait_for_event_and_check "inferior started" thread "body reason" started |
de7d7cb5 | 109 | |
d4c4ea75 SM |
110 | # While waiting for the stopped event, we might receive breakpoint changed |
111 | # events indicating some breakpoint addresses were relocated. Update INSN_PC | |
112 | # if necessary. | |
113 | lassign [dap_wait_for_event_and_check "stopped at function breakpoint" stopped \ | |
114 | "body reason" breakpoint \ | |
115 | "body hitBreakpointIds" $fn_bpno] unused objs | |
116 | foreach obj $objs { | |
117 | if { [dict get $obj "type"] != "event" } { | |
118 | continue | |
119 | } | |
120 | ||
121 | if { [dict get $obj "event"] != "breakpoint" } { | |
122 | continue | |
123 | } | |
124 | ||
125 | set body [dict get $obj "body"] | |
126 | ||
127 | if { [dict get $body "reason"] != "changed" } { | |
128 | continue | |
129 | } | |
130 | ||
131 | set breakpoint [dict get $body "breakpoint"] | |
132 | set breakpoint_id [dict get $breakpoint "id"] | |
133 | ||
134 | if { $breakpoint_id != $insn_bpno } { | |
135 | continue | |
136 | } | |
137 | ||
138 | set insn_pc [dict get $breakpoint "instructionReference"] | |
139 | } | |
de7d7cb5 TT |
140 | |
141 | set obj [dap_check_request_and_response "evaluate global in function" \ | |
142 | evaluate {o expression [s global_variable]}] | |
143 | dap_match_values "global value in function" [lindex $obj 0] \ | |
144 | "body result" 23 | |
145 | ||
146 | dap_check_request_and_response step stepIn {o threadId [i 1]} | |
59db4c93 | 147 | dap_wait_for_event_and_check "stopped after step" stopped "body reason" step |
de7d7cb5 TT |
148 | |
149 | set obj [dap_check_request_and_response "evaluate global second time" \ | |
150 | evaluate {o expression [s global_variable]}] | |
151 | dap_match_values "global value after step" [lindex $obj 0] \ | |
152 | "body result" 24 | |
153 | ||
fc2d72af TT |
154 | dap_check_request_and_response "continue to address" continue \ |
155 | {o threadId [i 1]} | |
59db4c93 | 156 | dap_wait_for_event_and_check "stopped at address breakpoint" stopped \ |
de7d7cb5 TT |
157 | "body reason" breakpoint \ |
158 | "body hitBreakpointIds" $insn_bpno | |
159 | ||
fc2d72af TT |
160 | dap_check_request_and_response "continue to line" continue \ |
161 | {o threadId [i 1]} | |
59db4c93 | 162 | dap_wait_for_event_and_check "stopped at line breakpoint" stopped \ |
de7d7cb5 | 163 | "body reason" breakpoint \ |
fc2d72af TT |
164 | "body hitBreakpointIds" $line_bpno \ |
165 | "body allThreadsStopped" true | |
de7d7cb5 | 166 | |
3eb64586 TT |
167 | dap_check_request_and_response "return from function" stepOut \ |
168 | {o threadId [i 1]} | |
169 | dap_wait_for_event_and_check "stopped after return" stopped \ | |
170 | "body reason" step | |
171 | ||
de7d7cb5 TT |
172 | set obj [dap_check_request_and_response "evaluate global in main" \ |
173 | evaluate {o expression [s global_variable]}] | |
174 | dap_match_values "global value in main" [lindex $obj 0] \ | |
175 | "body result" 25 | |
176 | ||
c2a0d767 TT |
177 | set obj [dap_check_request_and_response "set global in main" \ |
178 | setExpression {o expression [s global_variable] value [s 23]}] | |
179 | dap_match_values "global value in main after set" [lindex $obj 0] \ | |
8115dffa TT |
180 | "body result" 23 \ |
181 | "body type" int | |
c2a0d767 | 182 | |
2e9a03fd | 183 | set obj [dap_request_and_response \ |
de7d7cb5 | 184 | evaluate {o expression [s nosuchvariable]}] |
faee1372 SM |
185 | set response [lindex $obj 0] |
186 | gdb_assert { [dict get $response success] == "false" } "result of invalid request" | |
de7d7cb5 TT |
187 | |
188 | set obj [dap_check_request_and_response "disassemble one instruction" \ | |
189 | disassemble \ | |
190 | [format {o memoryReference [s %s] instructionCount [i 1]} \ | |
191 | $insn_pc]] | |
faee1372 SM |
192 | set response [lindex $obj 0] |
193 | gdb_assert { [dict exists $response body instructions] } "instructions in disassemble output" | |
de7d7cb5 | 194 | |
84bc96de TT |
195 | set obj [dap_check_request_and_response "command repl" \ |
196 | evaluate {o expression [s {output 23}] context [s repl]}] | |
197 | set response [lindex $obj 0] | |
198 | gdb_assert {[dict get $response body result] == 23} | |
199 | ||
a0b70d99 TT |
200 | set obj [dap_check_request_and_response sources loadedSources] |
201 | gdb_assert {[string first basic-dap.c $obj] != -1} | |
202 | ||
de7d7cb5 | 203 | dap_shutdown |