[GH-ISSUE #2380] [Design] Managed .NET debugger sessions with CLR, module and stop-scoped value identity #792

Open
opened 2026-10-15 18:28:23 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @matbrgz on GitHub (Oct 12, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2380

Type: Architecture / RFC Status: Proposed Ecosystem: REA

Analyst question

At a breakpoint or exception in my .NET application, which managed method/version, source location and available values explain the stop?

Current managed inspection is static; observing a process does not establish CLR execution. Portable PDB work (#2351) is a source-mapping foundation, not a runtime debugger.

Proposed first lane

Evaluate a caller-installed CoreCLR debugger such as netcoredbg through its DAP interface. Record the selected adapter digest/version and supported runtime/host matrix. .NET Framework, Mono, NativeAOT and mixed-mode debugging remain separately reported capabilities.

  • Separate exact launch configuration from explicit attach; reuse process generation/ownership and shared debugger-session rules from #1267.
  • Qualify managed method tokens by observed module identity and runtime/code version. Preserve generic instantiations and async/generated-frame attribution rather than presenting an inferred original frame as observed.
  • Bind PDB/source positions to exact module evidence; retain missing, mismatch and hidden sequence-point states.
  • Read stopped threads, frames, primitive locals and raw fields with bounded expansion.
  • Avoid implicit property evaluation, ToString, debugger-display calls and function evaluation. Each can execute target code; general expression evaluation and writes are separate scope decisions.
  • Preserve pending breakpoints, exception classification, stop-scoped reference invalidation and adapter-specific limitations.

Acceptance

  • An owned source-built CoreCLR fixture hits line/method/exception stops through CLI and MCP.
  • Tests cover same-named modules, a mismatched PDB, generics, async methods, optimized locals and abrupt process exit.
  • A getter/ToString with an observable counter is not invoked by inspection.
  • Stale frame/variable references after resume are rejected, not replayed as current values.
  • Cancellation releases owned adapter resources and reports target detach/termination according to launch or attach ownership.
  • One managed-debugger spec/plan and actual provider verification precede support claims.

Integration decision and references

New runtime provider: CONTRIBUTING.md requires an explicit maintainer scope decision before substantial implementation for integration. Adapter defaults and evaluated-expression paths need review; DAP alone does not establish effects.

Originally created by @matbrgz on GitHub (Oct 12, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2380 [![Type: Architecture / RFC](https://img.shields.io/badge/type-architecture_%2F_RFC-darkred.svg?style=flat-square)](https://github.com/morluto/rea) [![Status: Proposed](https://img.shields.io/badge/status-proposed-blue.svg?style=flat-square)](https://github.com/morluto/rea) [![Ecosystem: REA](https://img.shields.io/badge/ecosystem-morluto%2Frea-8A2BE2.svg?style=flat-square)](https://github.com/morluto/rea) ## Analyst question At a breakpoint or exception in my .NET application, which managed method/version, source location and available values explain the stop? Current managed inspection is static; observing a process does not establish CLR execution. Portable PDB work (#2351) is a source-mapping foundation, not a runtime debugger. ## Proposed first lane Evaluate a caller-installed CoreCLR debugger such as netcoredbg through its DAP interface. Record the selected adapter digest/version and supported runtime/host matrix. .NET Framework, Mono, NativeAOT and mixed-mode debugging remain separately reported capabilities. - Separate exact launch configuration from explicit attach; reuse process generation/ownership and shared debugger-session rules from #1267. - Qualify managed method tokens by observed module identity and runtime/code version. Preserve generic instantiations and async/generated-frame attribution rather than presenting an inferred original frame as observed. - Bind PDB/source positions to exact module evidence; retain missing, mismatch and hidden sequence-point states. - Read stopped threads, frames, primitive locals and raw fields with bounded expansion. - Avoid implicit property evaluation, ToString, debugger-display calls and function evaluation. Each can execute target code; general expression evaluation and writes are separate scope decisions. - Preserve pending breakpoints, exception classification, stop-scoped reference invalidation and adapter-specific limitations. ## Acceptance - [ ] An owned source-built CoreCLR fixture hits line/method/exception stops through CLI and MCP. - [ ] Tests cover same-named modules, a mismatched PDB, generics, async methods, optimized locals and abrupt process exit. - [ ] A getter/ToString with an observable counter is not invoked by inspection. - [ ] Stale frame/variable references after resume are rejected, not replayed as current values. - [ ] Cancellation releases owned adapter resources and reports target detach/termination according to launch or attach ownership. - [ ] One managed-debugger spec/plan and actual provider verification precede support claims. ## Integration decision and references New runtime provider: CONTRIBUTING.md requires an explicit maintainer scope decision before substantial implementation for integration. Adapter defaults and evaluated-expression paths need review; DAP alone does not establish effects. - [CoreCLR debugger interface](https://learn.microsoft.com/en-us/dotnet/core/unmanaged-api/debugging/icordebug/icordebug-interface) - [netcoredbg provider capabilities](https://github.com/Samsung/netcoredbg) - [DAP protocol](https://microsoft.github.io/debug-adapter-protocol/specification) - Static managed foundations: #2351; recorded EventPipe is #2370.
Author
Owner

@matbrgz commented on GitHub (Oct 12, 2026):

Design & Scope Boundary Notes

Objective (ELI5):
Provide live debugging observation for managed .NET processes (CoreCLR / .NET 6-9) preserving thread stacks, frame arguments, and object identities scoped to explicit breakpoint stops.

Safety Invariants:

  • Observation only: No function evaluation (FuncEval) or implicit property getter calls during inspection to avoid state mutations or deadlocks on the target process.
  • Supervision: Target must run under src/process/ supervision with guaranteed cleanup on disconnect or abort.
<!-- gh-comment-id:6133882155 --> @matbrgz commented on GitHub (Oct 12, 2026): ### Design & Scope Boundary Notes **Objective (ELI5):** Provide live debugging observation for managed .NET processes (CoreCLR / .NET 6-9) preserving thread stacks, frame arguments, and object identities scoped to explicit breakpoint stops. **Safety Invariants:** - Observation only: No function evaluation (`FuncEval`) or implicit property getter calls during inspection to avoid state mutations or deadlocks on the target process. - Supervision: Target must run under `src/process/` supervision with guaranteed cleanup on disconnect or abort.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#792
No description provided.