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
This commit is contained in:
Tom Tromey 2023-10-06 14:30:46 -06:00
parent 1f6ce80388
commit 14e461bed4
3 changed files with 41 additions and 1 deletions

View 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",

View 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)

View 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]}] \