mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-15 04:31:49 +08:00
25558d2fc0
Co-workers at AdaCore pointed out that gdb incorrectly implements the DAP launch and configurationDone requests. It's somewhat strange to me, but the spec does in fact say that configuration requests should occur before the executable is known to gdb. This was clarified in this bug report against the spec: https://github.com/microsoft/debug-adapter-protocol/issues/452 Fixing 'launch' to start the inferior was straightforward, but this then required some changes to how breakpoints are handled. In particular, now gdb will emit the "pending" reason on a breakpoint, and will suppress breakpoint events during breakpoint setting.
122 lines
3.7 KiB
Plaintext
122 lines
3.7 KiB
Plaintext
# Copyright 2023-2024 Free Software Foundation, Inc.
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# Test the handling of non-Value responses from 'children' method.
|
|
|
|
require allow_dap_tests
|
|
|
|
load_lib dap-support.exp
|
|
|
|
standard_testfile lazy-string.c
|
|
|
|
if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} {
|
|
return
|
|
}
|
|
|
|
set remote_python_file [gdb_remote_download host \
|
|
${srcdir}/${subdir}/${testfile}.py]
|
|
|
|
save_vars GDBFLAGS {
|
|
append GDBFLAGS " -iex \"source $remote_python_file\""
|
|
|
|
if {[dap_initialize] == ""} {
|
|
return
|
|
}
|
|
}
|
|
|
|
set line [gdb_get_line_number "STOP"]
|
|
set obj [dap_check_request_and_response "set breakpoint by line number" \
|
|
setBreakpoints \
|
|
[format {o source [o path [%s]] breakpoints [a [o line [i %d]]]} \
|
|
[list s $srcfile] $line]]
|
|
set line_bpno [dap_get_breakpoint_number $obj]
|
|
|
|
dap_check_request_and_response "configurationDone" configurationDone
|
|
|
|
if {[dap_launch $testfile] == ""} {
|
|
return
|
|
}
|
|
dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
|
|
"body reason" breakpoint \
|
|
"body hitBreakpointIds" $line_bpno
|
|
|
|
set bt [lindex [dap_check_request_and_response "backtrace" stackTrace \
|
|
{o threadId [i 1]}] \
|
|
0]
|
|
set frame_id [dict get [lindex [dict get $bt body stackFrames] 0] id]
|
|
|
|
set scopes [dap_check_request_and_response "get scopes" scopes \
|
|
[format {o frameId [i %d]} $frame_id]]
|
|
set scopes [dict get [lindex $scopes 0] body scopes]
|
|
|
|
lassign $scopes scope reg_scope
|
|
gdb_assert {[dict get $scope name] == "Locals"} "scope is locals"
|
|
gdb_assert {[dict get $scope namedVariables] == 1} "one var in scope"
|
|
|
|
set num [dict get $scope variablesReference]
|
|
set refs [lindex [dap_check_request_and_response "fetch variable" \
|
|
"variables" \
|
|
[format {o variablesReference [i %d] count [i 1]} \
|
|
$num]] \
|
|
0]
|
|
|
|
set vars [dict get $refs body variables]
|
|
gdb_assert {[llength $vars] == 1} "just one variable"
|
|
|
|
set var [lindex $vars 0]
|
|
gdb_assert {[dict get $var name] == "the_string"} "variable name"
|
|
gdb_assert {[dict get $var value] == "contents"} "variable value"
|
|
gdb_assert {[dict get $var namedVariables] == 2} "variable has two children"
|
|
|
|
set num [dict get $var variablesReference]
|
|
set refs [lindex [dap_check_request_and_response "fetch children of variable" \
|
|
"variables" \
|
|
[format {o variablesReference [i %d] count [i 2]} \
|
|
$num]] \
|
|
0]
|
|
|
|
set vars [dict get $refs body variables]
|
|
gdb_assert {[llength $vars] == 2} "got two children of variable"
|
|
|
|
set saw_first 0
|
|
set saw_second 0
|
|
foreach var [dict get $refs body variables] {
|
|
set name [dict get $var name]
|
|
switch $name {
|
|
"first" {
|
|
gdb_assert {[dict get $var value] == 23} "value of first"
|
|
incr saw_first
|
|
}
|
|
|
|
"second" {
|
|
# The result looks strange here, but only because TON does
|
|
# not handle the backslash-quote sequence properly when
|
|
# decoding the JSON. The actual JSON is: "value":
|
|
# "\"DEI\"".
|
|
gdb_assert {[dict get $var value] == "\\\"DEI\\\""} \
|
|
"value of second"
|
|
incr saw_second
|
|
}
|
|
|
|
default {
|
|
fail "unknown variable $name"
|
|
}
|
|
}
|
|
}
|
|
|
|
gdb_assert {$saw_first == 1 && $saw_second == 1} "saw both children"
|
|
|
|
dap_shutdown
|