aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2023-02-16 07:49:33 -0700
committerTom Tromey <tromey@adacore.com>2023-03-24 10:05:51 -0600
commit84bc96de16b64ae67460bf4896379a7543cecfd3 (patch)
tree35ac2c933b06f7cfaad63cbca3ef3913fbef7c56
parent9ed6d7410c800c331d1f24051c85e4e52d7dfced (diff)
downloadbinutils-84bc96de16b64ae67460bf4896379a7543cecfd3.zip
binutils-84bc96de16b64ae67460bf4896379a7543cecfd3.tar.gz
binutils-84bc96de16b64ae67460bf4896379a7543cecfd3.tar.bz2
Implement repl evaluation for DAP
The evaluate command supports a "context" parameter which tells the adapter the context in which an evaluation occurs. One of the supported values is "repl", which we took to mean evaluation of a gdb command. That is what this patch implements. Note that some gdb commands probably will not work correctly with the rest of the protocol. For example if the user types "continue", confusion may result. This patch requires the earlier patch to fix up scopes in DAP.
-rw-r--r--gdb/python/lib/gdb/dap/evaluate.py24
-rw-r--r--gdb/testsuite/gdb.dap/basic-dap.exp5
2 files changed, 26 insertions, 3 deletions
diff --git a/gdb/python/lib/gdb/dap/evaluate.py b/gdb/python/lib/gdb/dap/evaluate.py
index d04ac16..55d41b0 100644
--- a/gdb/python/lib/gdb/dap/evaluate.py
+++ b/gdb/python/lib/gdb/dap/evaluate.py
@@ -38,12 +38,30 @@ def _evaluate(expr, frame_id):
return ref.to_object()
+# Helper function to evaluate a gdb command in a certain frame.
+@in_gdb_thread
+def _repl(command, frame_id):
+ if frame_id is not None:
+ frame = frame_for_id(frame_id)
+ frame.select()
+ val = gdb.execute(command, from_tty=True, to_string=True)
+ return {
+ "result": val,
+ "variablesReference": 0,
+ }
+
+
# FIXME 'format' & hex
# FIXME supportsVariableType handling
-# FIXME "repl"
@request("evaluate")
-def eval_request(*, expression, frameId=None, **args):
- return send_gdb_with_response(lambda: _evaluate(expression, frameId))
+def eval_request(*, expression, frameId=None, context="variables", **args):
+ if context in ("watch", "variables"):
+ # These seem to be expression-like.
+ return send_gdb_with_response(lambda: _evaluate(expression, frameId))
+ elif context == "repl":
+ return send_gdb_with_response(lambda: _repl(expression, frameId))
+ else:
+ raise Exception(f'unknown evaluate context "{context}"')
@in_gdb_thread
diff --git a/gdb/testsuite/gdb.dap/basic-dap.exp b/gdb/testsuite/gdb.dap/basic-dap.exp
index 6f14df5..5e6e1b5 100644
--- a/gdb/testsuite/gdb.dap/basic-dap.exp
+++ b/gdb/testsuite/gdb.dap/basic-dap.exp
@@ -163,4 +163,9 @@ set obj [dap_check_request_and_response "disassemble one instruction" \
set response [lindex $obj 0]
gdb_assert { [dict exists $response body instructions] } "instructions in disassemble output"
+set obj [dap_check_request_and_response "command repl" \
+ evaluate {o expression [s {output 23}] context [s repl]}]
+set response [lindex $obj 0]
+gdb_assert {[dict get $response body result] == 23}
+
dap_shutdown