diff options
author | Tom Tromey <tromey@adacore.com> | 2025-07-29 07:48:21 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2025-08-11 07:39:10 -0600 |
commit | ddd2795c52228cbbdf11aa95e11b68647b10df88 (patch) | |
tree | 830a5899a4f514f4de280f65b56b41faecd968b0 | |
parent | 3c64cee8151d925ac3c438026074a2a1491e275f (diff) | |
download | gdb-ddd2795c52228cbbdf11aa95e11b68647b10df88.zip gdb-ddd2795c52228cbbdf11aa95e11b68647b10df88.tar.gz gdb-ddd2795c52228cbbdf11aa95e11b68647b10df88.tar.bz2 |
Do not allow DAP clients to dereference "void *"
While investigating a different bug, I noticed that the DAP code would
report a "void *"-typed register as having children -- however,
requesting the children of this register would fail.
The issue here is that a plain "void *" can't be dereferenced. This
patch changes the default visualizer to treat a "void *" as a scalar.
This adds a new test; but also arranges to examine all the returned
registers -- this was the first thing I attempted and it seemed
reasonable to have a test that double-checks that all the registers
really can be dereferenced as appropriate.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33228
-rw-r--r-- | gdb/python/lib/gdb/printing.py | 14 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dap/scopes.c | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dap/scopes.exp | 30 |
3 files changed, 36 insertions, 10 deletions
diff --git a/gdb/python/lib/gdb/printing.py b/gdb/python/lib/gdb/printing.py index cba27d2..cda033f 100644 --- a/gdb/python/lib/gdb/printing.py +++ b/gdb/python/lib/gdb/printing.py @@ -415,11 +415,17 @@ def make_visualizer(value): result = NoOpArrayPrinter(ty, value) elif ty.code in (gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION): result = NoOpStructPrinter(ty, value) - elif ty.code in ( - gdb.TYPE_CODE_PTR, - gdb.TYPE_CODE_REF, - gdb.TYPE_CODE_RVALUE_REF, + elif ( + ty.code + in ( + gdb.TYPE_CODE_PTR, + gdb.TYPE_CODE_REF, + gdb.TYPE_CODE_RVALUE_REF, + ) + and ty.target().code != gdb.TYPE_CODE_VOID ): + # Note we avoid "void *" here because those pointers can't + # be dereferenced without a cast. result = NoOpPointerReferencePrinter(value) else: result = NoOpScalarPrinter(value) diff --git a/gdb/testsuite/gdb.dap/scopes.c b/gdb/testsuite/gdb.dap/scopes.c index d8929f1..2a1d76c 100644 --- a/gdb/testsuite/gdb.dap/scopes.c +++ b/gdb/testsuite/gdb.dap/scopes.c @@ -27,6 +27,8 @@ int main () static int scalar = 23; + void *ptr = (void *) &scalar; + { const char *inner = "inner block"; diff --git a/gdb/testsuite/gdb.dap/scopes.exp b/gdb/testsuite/gdb.dap/scopes.exp index 59d344b..b2066e5 100644 --- a/gdb/testsuite/gdb.dap/scopes.exp +++ b/gdb/testsuite/gdb.dap/scopes.exp @@ -70,7 +70,8 @@ lassign $scopes scope reg_scope gdb_assert {[dict get $scope name] == "Locals"} "scope is locals" gdb_assert {[dict get $scope presentationHint] == "locals"} \ "locals presentation hint" -gdb_assert {[dict get $scope namedVariables] == 3} "three vars in scope" +set count [dict get $scope namedVariables] +gdb_assert {$count == 4} "four vars in scope" gdb_assert {[dict get $reg_scope name] == "Registers"} \ "second scope is registers" @@ -89,8 +90,8 @@ set refs1 [lindex [dap_check_request_and_response "fetch variables 0,1" \ set refs2 [lindex [dap_check_request_and_response "fetch variables 2" \ "variables" \ [format {o variablesReference [i %d] \ - start [i 2] count [i 1]} \ - $num]] \ + start [i 2] count [i %d]} \ + $num [expr {$count - 2}]]] \ 0] set vars [concat [dict get $refs1 body variables] \ @@ -115,6 +116,10 @@ foreach var $vars { "scalar" { gdb_assert {[dict get $var value] == 23} "check value of scalar" } + "ptr" { + gdb_assert {[dict get $var memoryReference] != ""} \ + "check memoryReference of ptr" + } default { fail "unknown variable $name" } @@ -129,10 +134,23 @@ set deivals [dict get $refs body variables] gdb_assert {[llength $deivals] == 2} "dei has two members" set num [dict get $reg_scope variablesReference] -# The request succeeding is sufficient. -set val [dap_check_request_and_response "fetch first register" \ +lassign [dap_check_request_and_response "fetch all registers" \ "variables" \ - [format {o variablesReference [i %d] count [i 1]} $num]] + [format {o variablesReference [i %d] count [i %d]} $num\ + [dict get $reg_scope namedVariables]]] \ + val events + +# If any register has children, try to fetch those as well. This is a +# regression test for part of PR dap/33228. +foreach var [dict get $val body variables] { + set regvar [dict get $var variablesReference] + if {$regvar > 0} { + dap_check_request_and_response "fetch register children for $regvar" \ + "variables" \ + [format {o variablesReference [i %d] count [i %d]} \ + $regvar [dict get $var namedVariables]] + } +} set num [dict get $scope variablesReference] set refs [lindex [dap_check_request_and_response "set variable scalar" \ |