diff options
-rw-r--r-- | gdb/python/lib/gdb/dap/breakpoint.py | 8 | ||||
-rw-r--r-- | gdb/python/lib/gdb/dap/evaluate.py | 12 | ||||
-rw-r--r-- | gdb/python/lib/gdb/dap/launch.py | 4 | ||||
-rw-r--r-- | gdb/python/lib/gdb/dap/sources.py | 6 | ||||
-rw-r--r-- | gdb/python/lib/gdb/dap/startup.py | 18 | ||||
-rw-r--r-- | gdb/python/lib/gdb/dap/varref.py | 6 |
6 files changed, 37 insertions, 17 deletions
diff --git a/gdb/python/lib/gdb/dap/breakpoint.py b/gdb/python/lib/gdb/dap/breakpoint.py index 33aa18e..c67bb47 100644 --- a/gdb/python/lib/gdb/dap/breakpoint.py +++ b/gdb/python/lib/gdb/dap/breakpoint.py @@ -24,7 +24,7 @@ from typing import Optional, Sequence from .server import request, capability, send_event from .sources import make_source -from .startup import in_gdb_thread, log_stack +from .startup import in_gdb_thread, log_stack, parse_and_eval, DAPException from .typecheck import type_check @@ -168,7 +168,7 @@ def _set_breakpoints_callback(kind, specs, creator): bp.ignore_count = 0 else: bp.ignore_count = int( - gdb.parse_and_eval(hit_condition, global_context=True) + parse_and_eval(hit_condition, global_context=True) ) # Reaching this spot means success. @@ -212,6 +212,7 @@ class _PrintBreakpoint(gdb.Breakpoint): # have already been stripped by the placement of the # regex capture in the 'split' call. try: + # No real need to use the DAP parse_and_eval here. val = gdb.parse_and_eval(item) output += str(val) except Exception as e: @@ -360,12 +361,13 @@ def _catch_exception(filterId, **args): if filterId in ("assert", "exception", "throw", "rethrow", "catch"): cmd = "-catch-" + filterId else: - raise Exception("Invalid exception filterID: " + str(filterId)) + raise DAPException("Invalid exception filterID: " + str(filterId)) result = gdb.execute_mi(cmd) # A little lame that there's no more direct way. for bp in gdb.breakpoints(): if bp.number == result["bkptno"]: return bp + # Not a DAPException because this is definitely unexpected. raise Exception("Could not find catchpoint after creating") diff --git a/gdb/python/lib/gdb/dap/evaluate.py b/gdb/python/lib/gdb/dap/evaluate.py index d39e787..eb38baf 100644 --- a/gdb/python/lib/gdb/dap/evaluate.py +++ b/gdb/python/lib/gdb/dap/evaluate.py @@ -20,7 +20,7 @@ from typing import Optional from .frames import select_frame from .server import capability, request, client_bool_capability -from .startup import in_gdb_thread +from .startup import in_gdb_thread, parse_and_eval, DAPException from .varref import find_variable, VariableReference, apply_format @@ -37,7 +37,7 @@ def _evaluate(expr, frame_id, value_format): if frame_id is not None: select_frame(frame_id) global_context = False - val = gdb.parse_and_eval(expr, global_context=global_context) + val = parse_and_eval(expr, global_context=global_context) ref = EvaluateResult(val) return ref.to_object() @@ -89,7 +89,7 @@ def eval_request( # Ignore the format for repl evaluation. return _repl(expression, frameId) else: - raise Exception('unknown evaluate context "' + context + '"') + raise DAPException('unknown evaluate context "' + context + '"') @request("variables") @@ -119,8 +119,8 @@ def set_expression( if frameId is not None: select_frame(frameId) global_context = False - lhs = gdb.parse_and_eval(expression, global_context=global_context) - rhs = gdb.parse_and_eval(value, global_context=global_context) + lhs = parse_and_eval(expression, global_context=global_context) + rhs = parse_and_eval(value, global_context=global_context) lhs.assign(rhs) return _SetResult(lhs).to_object() @@ -133,6 +133,6 @@ def set_variable( with apply_format(format): var = find_variable(variablesReference) lhs = var.find_child_by_name(name) - rhs = gdb.parse_and_eval(value) + rhs = parse_and_eval(value) lhs.assign(rhs) return lhs.to_object() diff --git a/gdb/python/lib/gdb/dap/launch.py b/gdb/python/lib/gdb/dap/launch.py index 675542c..5f95bfd 100644 --- a/gdb/python/lib/gdb/dap/launch.py +++ b/gdb/python/lib/gdb/dap/launch.py @@ -20,7 +20,7 @@ from typing import Mapping, Optional, Sequence from .events import exec_and_expect_stop, expect_process from .server import request, capability -from .startup import exec_and_log +from .startup import exec_and_log, DAPException # The program being launched, or None. This should only be accessed @@ -86,7 +86,7 @@ def attach( elif target is not None: cmd = "target remote " + target else: - raise Exception("attach requires either 'pid' or 'target'") + raise DAPException("attach requires either 'pid' or 'target'") expect_process("attach") exec_and_log(cmd) diff --git a/gdb/python/lib/gdb/dap/sources.py b/gdb/python/lib/gdb/dap/sources.py index 821205c..d73a3f8 100644 --- a/gdb/python/lib/gdb/dap/sources.py +++ b/gdb/python/lib/gdb/dap/sources.py @@ -18,7 +18,7 @@ import os import gdb from .server import request, capability -from .startup import in_gdb_thread +from .startup import in_gdb_thread, DAPException # The next available source reference ID. Must be greater than 0. @@ -68,11 +68,11 @@ def decode_source(source): if "path" in source: return source["path"] if "sourceReference" not in source: - raise Exception("either 'path' or 'sourceReference' must appear in Source") + raise DAPException("either 'path' or 'sourceReference' must appear in Source") ref = source["sourceReference"] global _id_map if ref not in _id_map: - raise Exception("no sourceReference " + str(ref)) + raise DAPException("no sourceReference " + str(ref)) return _id_map[ref]["path"] diff --git a/gdb/python/lib/gdb/dap/startup.py b/gdb/python/lib/gdb/dap/startup.py index 1d3b947..64a4659 100644 --- a/gdb/python/lib/gdb/dap/startup.py +++ b/gdb/python/lib/gdb/dap/startup.py @@ -39,6 +39,24 @@ _gdb_thread = threading.current_thread() _dap_thread = None +# "Known" exceptions are wrapped in a DAP exception, so that, by +# default, only rogue exceptions are logged -- this is then used by +# the test suite. +class DAPException(Exception): + pass + + +# Wrapper for gdb.parse_and_eval that turns exceptions into +# DAPException. +def parse_and_eval(expression, global_context=False): + try: + return gdb.parse_and_eval(expression, global_context=global_context) + except Exception as e: + # Be sure to preserve the summary, as this can propagate to + # the client. + raise DAPException(str(e)) from e + + def start_thread(name, target, args=()): """Start a new thread, invoking TARGET with *ARGS there. This is a helper function that ensures that any GDB signals are diff --git a/gdb/python/lib/gdb/dap/varref.py b/gdb/python/lib/gdb/dap/varref.py index 8f0a070..c75afe3 100644 --- a/gdb/python/lib/gdb/dap/varref.py +++ b/gdb/python/lib/gdb/dap/varref.py @@ -14,7 +14,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import gdb -from .startup import in_gdb_thread +from .startup import in_gdb_thread, DAPException from .server import client_bool_capability from abc import ABC, abstractmethod from collections import defaultdict @@ -165,7 +165,7 @@ class BaseReference(ABC): # map here. if name in self.by_name: return self.by_name[name] - raise Exception("no variable named '" + name + "'") + raise DAPException("no variable named '" + name + "'") class VariableReference(BaseReference): @@ -271,5 +271,5 @@ def find_variable(ref): # Variable references are offset by 1. ref = ref - 1 if ref < 0 or ref > len(all_variables): - raise Exception("invalid variablesReference") + raise DAPException("invalid variablesReference") return all_variables[ref] |