aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2023-09-27 11:48:24 -0600
committerTom Tromey <tromey@adacore.com>2023-10-16 08:40:18 -0600
commited5504c7b6f53ee3343ddd44ad2c8d28b00f7641 (patch)
treebb61e2286de3dcadae023e31693e2ba8347117b3 /gdb/python
parent1d45d90934b10862c00a22bcf4075815a785001b (diff)
downloadgdb-ed5504c7b6f53ee3343ddd44ad2c8d28b00f7641.zip
gdb-ed5504c7b6f53ee3343ddd44ad2c8d28b00f7641.tar.gz
gdb-ed5504c7b6f53ee3343ddd44ad2c8d28b00f7641.tar.bz2
Add DAP scope cache
Andry Ogorodnik, a co-worker, noticed that multiple "scopes" requests with the same frame would yield different variableReference values in the response. This patch adds a regression test for this, and adds a scope cache in scopes.py, ensuring that multiple identical requests will get the same response. Tested-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/lib/gdb/dap/scopes.py38
1 files changed, 29 insertions, 9 deletions
diff --git a/gdb/python/lib/gdb/dap/scopes.py b/gdb/python/lib/gdb/dap/scopes.py
index 4874d00..5dde060 100644
--- a/gdb/python/lib/gdb/dap/scopes.py
+++ b/gdb/python/lib/gdb/dap/scopes.py
@@ -21,6 +21,21 @@ from .server import request
from .varref import BaseReference
+# Map DAP frame IDs to scopes. This ensures that scopes are re-used.
+frame_to_scope = {}
+
+
+# When the inferior is re-started, we erase all scope references. See
+# the section "Lifetime of Objects References" in the spec.
+@in_gdb_thread
+def clear_scopes(event):
+ global frame_to_scope
+ frame_to_scope = {}
+
+
+gdb.events.cont.connect(clear_scopes)
+
+
class _ScopeReference(BaseReference):
def __init__(self, name, hint, frame, var_list):
super().__init__(name)
@@ -83,15 +98,20 @@ class _RegisterReference(_ScopeReference):
# Helper function to create a DAP scopes for a given frame ID.
@in_gdb_thread
def _get_scope(id):
- frame = frame_for_id(id)
- scopes = []
- args = frame.frame_args()
- if args:
- scopes.append(_ScopeReference("Arguments", "arguments", frame, args))
- locs = frame.frame_locals()
- if locs:
- scopes.append(_ScopeReference("Locals", "locals", frame, locs))
- scopes.append(_RegisterReference("Registers", frame))
+ global frame_to_scope
+ if id in frame_to_scope:
+ scopes = frame_to_scope[id]
+ else:
+ frame = frame_for_id(id)
+ scopes = []
+ args = frame.frame_args()
+ if args:
+ scopes.append(_ScopeReference("Arguments", "arguments", frame, args))
+ locs = frame.frame_locals()
+ if locs:
+ scopes.append(_ScopeReference("Locals", "locals", frame, locs))
+ scopes.append(_RegisterReference("Registers", frame))
+ frame_to_scope[id] = scopes
return [x.to_object() for x in scopes]