GDB (xrefs)
Loading...
Searching...
No Matches
evaluate.py
Go to the documentation of this file.
1# Copyright 2022, 2023 Free Software Foundation, Inc.
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16import gdb
17
18# This is deprecated in 3.9, but required in older versions.
19from typing import Optional
20
21from .frames import select_frame
22from .server import capability, request, client_bool_capability
23from .startup import in_gdb_thread
24from .varref import find_variable, VariableReference, apply_format
25
26
28 def __init__(self, value):
29 super().__init__(None, value, "result")
30
31
32# Helper function to evaluate an expression in a certain frame.
33@in_gdb_thread
34def _evaluate(expr, frame_id, value_format):
35 with apply_format(value_format):
36 global_context = True
37 if frame_id is not None:
38 select_frame(frame_id)
39 global_context = False
40 val = gdb.parse_and_eval(expr, global_context=global_context)
41 ref = EvaluateResult(val)
42 return ref.to_object()
43
44
45# Like _evaluate but ensure that the expression cannot cause side
46# effects.
47@in_gdb_thread
48def _eval_for_hover(expr, frame_id, value_format):
49 with gdb.with_parameter("may-write-registers", "off"):
50 with gdb.with_parameter("may-write-memory", "off"):
51 with gdb.with_parameter("may-call-functions", "off"):
52 return _evaluate(expr, frame_id, value_format)
53
54
56 def __init__(self, value):
57 super().__init__(None, value, "value")
58
59
60# Helper function to perform an assignment.
61@in_gdb_thread
62def _set_expression(expression, value, frame_id, value_format):
63 with apply_format(value_format):
64 global_context = True
65 if frame_id is not None:
66 select_frame(frame_id)
67 global_context = False
68 lhs = gdb.parse_and_eval(expression, global_context=global_context)
69 rhs = gdb.parse_and_eval(value, global_context=global_context)
70 lhs.assign(rhs)
71 return _SetResult(lhs).to_object()
72
73
74# Helper function to evaluate a gdb command in a certain frame.
75@in_gdb_thread
76def _repl(command, frame_id):
77 if frame_id is not None:
78 select_frame(frame_id)
79 val = gdb.execute(command, from_tty=True, to_string=True)
80 return {
81 "result": val,
82 "variablesReference": 0,
83 }
84
85
86@request("evaluate")
87@capability("supportsEvaluateForHovers")
88@capability("supportsValueFormattingOptions")
89def eval_request(
90 *,
91 expression: str,
92 frameId: Optional[int] = None,
93 context: str = "variables",
94 format=None,
95 **args,
96):
97 if context in ("watch", "variables"):
98 # These seem to be expression-like.
99 return _evaluate(expression, frameId, format)
100 elif context == "hover":
101 return _eval_for_hover(expression, frameId, format)
102 elif context == "repl":
103 # Ignore the format for repl evaluation.
104 return _repl(expression, frameId)
105 else:
106 raise Exception('unknown evaluate context "' + context + '"')
107
108
109@in_gdb_thread
110def _variables(ref, start, count, value_format):
111 with apply_format(value_format):
112 var = find_variable(ref)
113 children = var.fetch_children(start, count)
114 return [x.to_object() for x in children]
115
116
117@request("variables")
118# Note that we ignore the 'filter' field. That seems to be
119# specific to javascript.
120def variables(
121 *, variablesReference: int, start: int = 0, count: int = 0, format=None, **args
122):
123 # This behavior was clarified here:
124 # https://github.com/microsoft/debug-adapter-protocol/pull/394
125 if not client_bool_capability("supportsVariablePaging"):
126 start = 0
127 count = 0
128 return {"variables": _variables(variablesReference, start, count, format)}
129
130
131@capability("supportsSetExpression")
132@request("setExpression")
134 *, expression: str, value: str, frameId: Optional[int] = None, format=None, **args
135):
136 return _set_expression(expression, value, frameId, format)
137
138
139# Helper function to perform an assignment.
140@in_gdb_thread
141def _set_variable(ref, name, value, value_format):
142 with apply_format(value_format):
143 var = find_variable(ref)
144 lhs = var.find_child_by_name(name)
145 rhs = gdb.parse_and_eval(value)
146 lhs.assign(rhs)
147 return lhs.to_object()
148
149
150@capability("supportsSetVariable")
151@request("setVariable")
152def set_variable(
153 *, variablesReference: int, name: str, value: str, format=None, **args
154):
155 return _set_variable(variablesReference, name, value, format)
_variables(ref, start, count, value_format)
Definition evaluate.py:110
eval_request(*str expression, Optional[int] frameId=None, str context="variables", format=None, **args)
Definition evaluate.py:96
_evaluate(expr, frame_id, value_format)
Definition evaluate.py:34
variables(*int variablesReference, int start=0, int count=0, format=None, **args)
Definition evaluate.py:122
_eval_for_hover(expr, frame_id, value_format)
Definition evaluate.py:48
_repl(command, frame_id)
Definition evaluate.py:76
_set_expression(expression, value, frame_id, value_format)
Definition evaluate.py:62
set_variable(*int variablesReference, str name, str value, format=None, **args)
Definition evaluate.py:154
_set_variable(ref, name, value, value_format)
Definition evaluate.py:141
set_expression(*str expression, str value, Optional[int] frameId=None, format=None, **args)
Definition evaluate.py:135
with_parameter(name, value)
Definition __init__.py:254