Skip to content

DAP trace: no parent/child connection discriminator — frames from all sockets interleave with independent seq spaces #518

Description

@debugmcpdev

Summary

DAP_TRACE=1 writes every frame of every MinimalDapClient in the proxy worker — parent connection, adopted child connection, release connections — into one dap-trace-<sessionId>.ndjson, with records of the shape {ts, direction, payload}. There is no field saying which connection carried the frame, and each client numbers its own seq space independently starting at 1.

For single-connection adapters that's fine. For js-debug's parent/child topology it makes the trace ambiguous exactly where it matters most: the #513 investigation needed to answer "did this pause go to the root session or the target session?", and the trace cannot say — two initialize requests with seq: 1 from two different sockets are byte-identical in the file.

What it cost in practice

During the #513 root-cause work (this trace: parent attach at 16:18:24.175, child adoption at .337, the swallowed pause at .342):

16:18:24.340 out request initialize   {"clientID": "mcp-child-175aaa8b…"}   <- child (identifiable only by clientID)
16:18:24.342 out request pause        {"threadId": 0}                        <- which socket??
16:18:24.343 out request setExceptionBreakpoints                             <- child config

Whether the pause went out on the parent socket (js-debug root: silent no-op) or the child socket (swallowed pre-attach) had to be reconstructed by correlating wall-clock timestamps against [MinimalDapClient] Dispatching '<cmd>' to child session lines in a different log file — workable once, but exactly the kind of manual joining a trace exists to avoid.

Suggested

Add a connection tag to each trace record, e.g. conn: "parent" / conn: "child:<pendingId8>" / conn: "release:<pendingId8>":

  • MinimalDapClient already knows which role it plays at construction time for children (ChildSessionManager creates them) — a constructor option traceLabel defaulting to "parent" would do it.
  • Keep the record shape otherwise unchanged so existing tooling that reads {ts, direction, payload} keeps working.

Optionally also include the client's clientID-style instance id in the header line the worker logs when tracing is enabled, so a reader can map labels to sockets without opening the code.

Environment

main @ 946054b (post-#514/#515), Linux, Node 22.22.3. Found while root-causing #513.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions