diff options
Diffstat (limited to 'gdb/python/lib')
| -rw-r--r-- | gdb/python/lib/gdb/dap/breakpoint.py | 134 | ||||
| -rw-r--r-- | gdb/python/lib/gdb/dap/launch.py | 29 |
2 files changed, 75 insertions, 88 deletions
diff --git a/gdb/python/lib/gdb/dap/breakpoint.py b/gdb/python/lib/gdb/dap/breakpoint.py index 87e7464..b4fb112 100644 --- a/gdb/python/lib/gdb/dap/breakpoint.py +++ b/gdb/python/lib/gdb/dap/breakpoint.py @@ -28,17 +28,6 @@ from .startup import in_gdb_thread, log_stack, parse_and_eval, LogLevel, DAPExce from .typecheck import type_check -@in_gdb_thread -def _bp_modified(event): - send_event( - "breakpoint", - { - "reason": "changed", - "breakpoint": _breakpoint_descriptor(event), - }, - ) - - # True when suppressing new breakpoint events. _suppress_bp = False @@ -56,6 +45,19 @@ def suppress_new_breakpoint_event(): @in_gdb_thread +def _bp_modified(event): + global _suppress_bp + if not _suppress_bp: + send_event( + "breakpoint", + { + "reason": "changed", + "breakpoint": _breakpoint_descriptor(event), + }, + ) + + +@in_gdb_thread def _bp_created(event): global _suppress_bp if not _suppress_bp: @@ -70,13 +72,15 @@ def _bp_created(event): @in_gdb_thread def _bp_deleted(event): - send_event( - "breakpoint", - { - "reason": "removed", - "breakpoint": _breakpoint_descriptor(event), - }, - ) + global _suppress_bp + if not _suppress_bp: + send_event( + "breakpoint", + { + "reason": "removed", + "breakpoint": _breakpoint_descriptor(event), + }, + ) gdb.events.breakpoint_created.connect(_bp_created) @@ -97,11 +101,10 @@ def _breakpoint_descriptor(bp): "Return the Breakpoint object descriptor given a gdb Breakpoint." result = { "id": bp.number, - # We always use True here, because this field just indicates - # that breakpoint creation was successful -- and if we have a - # breakpoint, the creation succeeded. - "verified": True, + "verified": not bp.pending, } + if bp.pending: + result["reason"] = "pending" if bp.locations: # Just choose the first location, because DAP doesn't allow # multiple locations. See @@ -146,52 +149,55 @@ def _set_breakpoints_callback(kind, specs, creator): saved_map = {} breakpoint_map[kind] = {} result = [] - for spec in specs: - # It makes sense to reuse a breakpoint even if the condition - # or ignore count differs, so remove these entries from the - # spec first. - (condition, hit_condition) = _remove_entries(spec, "condition", "hitCondition") - keyspec = frozenset(spec.items()) - - # Create or reuse a breakpoint. If asked, set the condition - # or the ignore count. Catch errors coming from gdb and - # report these as an "unverified" breakpoint. - bp = None - try: - if keyspec in saved_map: - bp = saved_map.pop(keyspec) - else: - with suppress_new_breakpoint_event(): + with suppress_new_breakpoint_event(): + for spec in specs: + # It makes sense to reuse a breakpoint even if the condition + # or ignore count differs, so remove these entries from the + # spec first. + (condition, hit_condition) = _remove_entries( + spec, "condition", "hitCondition" + ) + keyspec = frozenset(spec.items()) + + # Create or reuse a breakpoint. If asked, set the condition + # or the ignore count. Catch errors coming from gdb and + # report these as an "unverified" breakpoint. + bp = None + try: + if keyspec in saved_map: + bp = saved_map.pop(keyspec) + else: bp = creator(**spec) - bp.condition = condition - if hit_condition is None: - bp.ignore_count = 0 - else: - bp.ignore_count = int( - parse_and_eval(hit_condition, global_context=True) + bp.condition = condition + if hit_condition is None: + bp.ignore_count = 0 + else: + bp.ignore_count = int( + parse_and_eval(hit_condition, global_context=True) + ) + + # Reaching this spot means success. + breakpoint_map[kind][keyspec] = bp + result.append(_breakpoint_descriptor(bp)) + # Exceptions other than gdb.error are possible here. + except Exception as e: + # Don't normally want to see this, as it interferes with + # the test suite. + log_stack(LogLevel.FULL) + # Maybe the breakpoint was made but setting an attribute + # failed. We still want this to fail. + if bp is not None: + bp.delete() + # Breakpoint creation failed. + result.append( + { + "verified": False, + "reason": "failed", + "message": str(e), + } ) - # Reaching this spot means success. - breakpoint_map[kind][keyspec] = bp - result.append(_breakpoint_descriptor(bp)) - # Exceptions other than gdb.error are possible here. - except Exception as e: - # Don't normally want to see this, as it interferes with - # the test suite. - log_stack(LogLevel.FULL) - # Maybe the breakpoint was made but setting an attribute - # failed. We still want this to fail. - if bp is not None: - bp.delete() - # Breakpoint creation failed. - result.append( - { - "verified": False, - "message": str(e), - } - ) - # Delete any breakpoints that were not reused. for entry in saved_map.values(): entry.delete() diff --git a/gdb/python/lib/gdb/dap/launch.py b/gdb/python/lib/gdb/dap/launch.py index 184af16..6783d99 100644 --- a/gdb/python/lib/gdb/dap/launch.py +++ b/gdb/python/lib/gdb/dap/launch.py @@ -23,16 +23,6 @@ from .server import request, capability from .startup import exec_and_log, DAPException -# The program being launched, or None. This should only be accessed -# from the gdb thread. -_program = None - - -# True if the program was attached, False otherwise. This should only -# be accessed from the gdb thread. -_attach = False - - # Any parameters here are necessarily extensions -- DAP requires this # from implementations. Any additions or changes here should be # documented in the gdb manual. @@ -46,10 +36,6 @@ def launch( stopAtBeginningOfMainSubprogram: bool = False, **extra, ): - global _program - _program = program - global _attach - _attach = False if cwd is not None: exec_and_log("cd " + cwd) if program is not None: @@ -64,6 +50,8 @@ def launch( inf.clear_env() for name, value in env.items(): inf.set_env(name, value) + expect_process("process") + exec_and_expect_stop("run") @request("attach") @@ -74,11 +62,6 @@ def attach( target: Optional[str] = None, **args, ): - # Ensure configurationDone does not try to run. - global _attach - _attach = True - global _program - _program = program if program is not None: exec_and_log("file " + program) if pid is not None: @@ -93,9 +76,7 @@ def attach( @capability("supportsConfigurationDoneRequest") -@request("configurationDone", response=False) +@request("configurationDone") def config_done(**args): - global _attach - if not _attach: - expect_process("process") - exec_and_expect_stop("run") + # Nothing to do. + return None |
