From: Tom Tromey Date: Tue, 29 Jul 2025 13:48:21 +0000 (-0600) Subject: Do not allow DAP clients to dereference "void *" X-Git-Tag: gdb-17-branchpoint~346 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ddd2795c52228cbbdf11aa95e11b68647b10df88;p=thirdparty%2Fbinutils-gdb.git 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 --- diff --git a/gdb/python/lib/gdb/printing.py b/gdb/python/lib/gdb/printing.py index cba27d29e6b..cda033f0e49 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 d8929f13c4c..2a1d76cdee7 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 59d344bcf3b..b2066e5276c 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" \