[v2] Respect supportsMemoryReferences in DAP

Message ID 20230731174826.2733368-1-tromey@adacore.com
State New
Headers
Series [v2] Respect supportsMemoryReferences in DAP |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed

Commit Message

Tom Tromey July 31, 2023, 5:48 p.m. UTC
  I noticed that the support for memoryReference in the "variables"
output is gated on the client "supportsMemoryReferences" capability.

This patch implements this and makes some other changes to the DAP
memory reference code:

* Remove the memoryReference special case from _SetResult.
  Upstream DAP fixed this oversight in response to
  https://github.com/microsoft/debug-adapter-protocol/issues/414

* Don't use the address of a variable as its memoryReference -- only
  emit this for pointer types.  There's no spec support for the
  previous approach.

* Use strip_typedefs to handle typedefs of pointers.
---
 gdb/python/lib/gdb/dap/evaluate.py |  7 -------
 gdb/python/lib/gdb/dap/varref.py   | 11 +++++++----
 gdb/testsuite/gdb.dap/memory.c     |  2 ++
 gdb/testsuite/gdb.dap/memory.exp   |  2 ++
 gdb/testsuite/lib/dap-support.exp  |  3 ++-
 5 files changed, 13 insertions(+), 12 deletions(-)
  

Patch

diff --git a/gdb/python/lib/gdb/dap/evaluate.py b/gdb/python/lib/gdb/dap/evaluate.py
index 63e80331b24..9fa94e08121 100644
--- a/gdb/python/lib/gdb/dap/evaluate.py
+++ b/gdb/python/lib/gdb/dap/evaluate.py
@@ -55,13 +55,6 @@  class _SetResult(VariableReference):
     def __init__(self, value):
         super().__init__(None, value, "value")
 
-    def to_object(self):
-        result = super().to_object()
-        # This is not specified in the setExpression result.
-        if "memoryReference" in result:
-            del result["memoryReference"]
-        return result
-
 
 # Helper function to perform an assignment.
 @in_gdb_thread
diff --git a/gdb/python/lib/gdb/dap/varref.py b/gdb/python/lib/gdb/dap/varref.py
index 213151fd3d3..0e0d92a8832 100644
--- a/gdb/python/lib/gdb/dap/varref.py
+++ b/gdb/python/lib/gdb/dap/varref.py
@@ -162,10 +162,13 @@  class VariableReference(BaseReference):
                 result["indexedVariables"] = num_children
             else:
                 result["namedVariables"] = num_children
-        if self.value.type.code == gdb.TYPE_CODE_PTR:
-            result["memoryReference"] = hex(int(self.value))
-        elif self.value.address is not None:
-            result["memoryReference"] = hex(int(self.value.address))
+        if client_bool_capability("supportsMemoryReferences"):
+            # https://github.com/microsoft/debug-adapter-protocol/issues/414
+            # changed DAP to allow memory references for any of the
+            # variable response requests, and to lift the restriction
+            # to pointer-to-function from Variable.
+            if self.value.type.strip_typedefs().code == gdb.TYPE_CODE_PTR:
+                result["memoryReference"] = hex(int(self.value))
         if client_bool_capability("supportsVariableType"):
             result["type"] = str(self.value.type)
         return result
diff --git a/gdb/testsuite/gdb.dap/memory.c b/gdb/testsuite/gdb.dap/memory.c
index 3b9f6138abe..630e23dcf01 100644
--- a/gdb/testsuite/gdb.dap/memory.c
+++ b/gdb/testsuite/gdb.dap/memory.c
@@ -19,6 +19,8 @@ 
 
 uint32_t thirty_two = 7;
 
+uint32_t *thirty_two_p = &thirty_two;
+
 int main ()
 {
   return 0;			/* BREAK */
diff --git a/gdb/testsuite/gdb.dap/memory.exp b/gdb/testsuite/gdb.dap/memory.exp
index ab0516d6b3d..d702d5b5dee 100644
--- a/gdb/testsuite/gdb.dap/memory.exp
+++ b/gdb/testsuite/gdb.dap/memory.exp
@@ -47,6 +47,8 @@  set obj [dap_check_request_and_response "evaluate global" \
 	     evaluate {o expression [s thirty_two]}]
 dap_match_values "global value" [lindex $obj 0] "body result" 7
 
+set obj [dap_check_request_and_response "evaluate global pointer" \
+	     evaluate {o expression [s thirty_two_p]}]
 set addr [dict get [lindex $obj 0] body memoryReference]
 
 set obj [dap_check_request_and_response "read memory" \
diff --git a/gdb/testsuite/lib/dap-support.exp b/gdb/testsuite/lib/dap-support.exp
index e3750e1d016..4183526a320 100644
--- a/gdb/testsuite/lib/dap-support.exp
+++ b/gdb/testsuite/lib/dap-support.exp
@@ -233,7 +233,8 @@  proc _dap_initialize {name} {
     return [dap_check_request_and_response $name initialize \
 		{o clientID [s "gdb testsuite"] \
 		     supportsVariableType [l true] \
-		     supportsVariablePaging [l true]}]
+		     supportsVariablePaging [l true] \
+		     supportsMemoryReferences [l true]}]
 }
 
 # Start gdb, send a DAP initialize request, and then a launch request