]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Do not allow DAP clients to dereference "void *"
authorTom Tromey <tromey@adacore.com>
Tue, 29 Jul 2025 13:48:21 +0000 (07:48 -0600)
committerTom Tromey <tromey@adacore.com>
Mon, 11 Aug 2025 13:39:10 +0000 (07:39 -0600)
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

gdb/python/lib/gdb/printing.py
gdb/testsuite/gdb.dap/scopes.c
gdb/testsuite/gdb.dap/scopes.exp

index cba27d29e6ba546b11ee408bc75d0486880382f4..cda033f0e4969f2071d7feb553032fa9aa8085d3 100644 (file)
@@ -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)
index d8929f13c4c124c0647375b7b96365430a709214..2a1d76cdee7ca1f1ea1e5ea645026d9238fed2b4 100644 (file)
@@ -27,6 +27,8 @@ int main ()
 
   static int scalar = 23;
 
+  void *ptr = (void *) &scalar;
+
   {
     const char *inner = "inner block";
 
index 59d344bcf3bd69fbec4d13a4f71ff0f81516863b..b2066e5276c9e5a957e3f5e3237c9c18df1ac559 100644 (file)
@@ -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" \