From 14e461bed44258fb872731a79ca5e82b70781d09 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 6 Oct 2023 14:30:46 -0600 Subject: Emit DAP "process" event DAP specifies a "process" event that is sent when a process is started or attached to. gdb was not emitting this (several DAP clients appear to ignore it entirely), but it looked easy and harmless to implement. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30473 --- gdb/python/lib/gdb/dap/events.py | 36 ++++++++++++++++++++++++++++++++++++ gdb/python/lib/gdb/dap/launch.py | 4 +++- gdb/testsuite/gdb.dap/pause.exp | 2 ++ 3 files changed, 41 insertions(+), 1 deletion(-) (limited to 'gdb') diff --git a/gdb/python/lib/gdb/dap/events.py b/gdb/python/lib/gdb/dap/events.py index 663b67e..b759ba4 100644 --- a/gdb/python/lib/gdb/dap/events.py +++ b/gdb/python/lib/gdb/dap/events.py @@ -44,8 +44,43 @@ def _on_exit(event): send_event("terminated") +# When None, a "process" event has already been sent. When a string, +# it is the "startMethod" for that event. +_process_event_kind = None + + +@in_gdb_thread +def send_process_event_once(): + global _process_event_kind + if _process_event_kind is not None: + inf = gdb.selected_inferior() + is_local = inf.connection.type == "native" + data = { + "isLocalProcess": is_local, + "startMethod": _process_event_kind, + # Could emit 'pointerSize' here too if we cared to. + } + if inf.progspace.filename: + data["name"] = inf.progspace.filename + if is_local: + data["systemProcessId"] = inf.pid + send_event("process", data) + _process_event_kind = None + + +@in_gdb_thread +def expect_process(reason): + """Indicate that DAP is starting or attaching to a process. + + REASON is the "startMethod" to include in the "process" event. + """ + global _process_event_kind + _process_event_kind = reason + + @in_gdb_thread def thread_event(event, reason): + send_process_event_once() send_event( "thread", { @@ -81,6 +116,7 @@ def _new_objfile(event): @in_gdb_thread def _objfile_removed(event): + send_process_event_once() if is_module(event.objfile): send_event( "module", diff --git a/gdb/python/lib/gdb/dap/launch.py b/gdb/python/lib/gdb/dap/launch.py index ab704c7..ee6ee05 100644 --- a/gdb/python/lib/gdb/dap/launch.py +++ b/gdb/python/lib/gdb/dap/launch.py @@ -18,7 +18,7 @@ import gdb # These are deprecated in 3.9, but required in older versions. from typing import Mapping, Optional, Sequence -from .events import exec_and_expect_stop +from .events import exec_and_expect_stop, expect_process from .server import request, capability from .startup import in_gdb_thread, exec_and_log @@ -75,6 +75,7 @@ def attach(*, pid: Optional[int] = None, target: Optional[str] = None, **args): cmd = "target remote " + target else: raise Exception("attach requires either 'pid' or 'target'") + expect_process("attach") exec_and_log(cmd) @@ -83,6 +84,7 @@ def attach(*, pid: Optional[int] = None, target: Optional[str] = None, **args): def config_done(**args): global _program if _program is not None: + expect_process("process") # Suppress the continue event, but don't set any particular # expected stop. exec_and_expect_stop("run", None) diff --git a/gdb/testsuite/gdb.dap/pause.exp b/gdb/testsuite/gdb.dap/pause.exp index 30ce609..1b65dca 100644 --- a/gdb/testsuite/gdb.dap/pause.exp +++ b/gdb/testsuite/gdb.dap/pause.exp @@ -42,6 +42,8 @@ dap_check_request_and_response "set conditional breakpoint" \ [list s $srcfile] $line] dap_check_request_and_response "start inferior" configurationDone +dap_wait_for_event_and_check "process event generated" process \ + "body startMethod" process dap_wait_for_event_and_check "inferior started" thread "body reason" started set resp [lindex [dap_request_and_response evaluate {o expression [s 23]}] \ -- cgit v1.1