]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Emit DAP "process" event
authorTom Tromey <tromey@adacore.com>
Fri, 6 Oct 2023 20:30:46 +0000 (14:30 -0600)
committerTom Tromey <tromey@adacore.com>
Tue, 28 Nov 2023 15:47:24 +0000 (08:47 -0700)
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
gdb/python/lib/gdb/dap/launch.py
gdb/testsuite/gdb.dap/pause.exp

index 663b67ea24e5d5c6c2a07e08f02c5ff35cd2648c..b759ba43b5f0949541227cc604af56fcb1d1ae56 100644 (file)
@@ -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",
index ab704c7a7ccfd5d89b1ee86c7064cfc9a09015e9..ee6ee05bac345e0fad8d3a32d6a703c4ae8af79b 100644 (file)
@@ -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)
index 30ce6095225d1df0a97b3990ea9ee1b95d1a9059..1b65dcac8364619e571d0485858d5aeeb2d547a4 100644 (file)
@@ -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]}] \