[Debugger] Define debugger safety guidance#8817
Conversation
There was a problem hiding this comment.
Pull request overview
Defines and documents safety boundaries for Debugger/Dynamic Instrumentation reflection and capture paths (to avoid unintended customer-code execution/type loading), and adds targeted tests that lock in the current “default capture vs allowed execution” behavior.
Changes:
- Added a “customer code execution” policy for snapshot capture and expression evaluation, clarifying what default capture must avoid and what specific features are allowed to execute (bounded) customer code.
- Added a reflection/type-loading audit document that classifies common debugger reflection risks (early runtime resolution,
.cctortriggering, customer code execution) and captures the current status of recent safety fixes. - Added focused snapshot tests that codify current behavior for default object capture (no arbitrary getters), exception property capture, and supported collection enumeration behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tracer/test/Datadog.Trace.Tests/Debugger/DebuggerSnapshotCreatorTests.cs | Adds regression tests for the current customer-code execution policy (getters, exception properties, collection enumeration/count). |
| docs/development/DebuggerReflectionLoadingAudit.md | New audit doc classifying debugger reflection/loading risks and documenting current mitigations. |
| docs/development/DebuggerCustomerCodeExecutionPolicy.md | New policy doc defining when debugger capture/expression paths may execute customer code vs must omit values with notCapturedReason. |
| AGENTS.md | Exposes the new audit/policy docs to reviewers/agents as required pre-review guidance for safety-sensitive debugger changes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8817) and master. ✅ No regressions detected - check the details below Full Metrics ComparisonFakeDbCommand
HttpMessageHandler
Comparison explanationExecution-time benchmarks measure the whole time it takes to execute a program, and are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are highlighted in **red**. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). Duration chartsFakeDbCommand (.NET Framework 4.8)gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8817) - mean (72ms) : 69, 76
master - mean (73ms) : 69, 76
section Bailout
This PR (8817) - mean (74ms) : 72, 77
master - mean (75ms) : 72, 78
section CallTarget+Inlining+NGEN
This PR (8817) - mean (1,078ms) : 1035, 1120
master - mean (1,082ms) : 1039, 1125
FakeDbCommand (.NET Core 3.1)gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8817) - mean (113ms) : 106, 120
master - mean (113ms) : 107, 118
section Bailout
This PR (8817) - mean (111ms) : 109, 113
master - mean (111ms) : 109, 112
section CallTarget+Inlining+NGEN
This PR (8817) - mean (779ms) : 751, 807
master - mean (777ms) : 752, 801
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8817) - mean (97ms) : 95, 100
master - mean (96ms) : 94, 99
section Bailout
This PR (8817) - mean (98ms) : 96, 100
master - mean (101ms) : 95, 106
section CallTarget+Inlining+NGEN
This PR (8817) - mean (941ms) : 899, 982
master - mean (937ms) : 894, 981
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8817) - mean (100ms) : 96, 105
master - mean (96ms) : 91, 102
section Bailout
This PR (8817) - mean (99ms) : 94, 105
master - mean (96ms) : 94, 97
section CallTarget+Inlining+NGEN
This PR (8817) - mean (811ms) : 779, 842
master - mean (814ms) : 777, 851
HttpMessageHandler (.NET Framework 4.8)gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8817) - mean (203ms) : 198, 208
master - mean (204ms) : 198, 209
section Bailout
This PR (8817) - mean (206ms) : 201, 212
master - mean (207ms) : 203, 212
section CallTarget+Inlining+NGEN
This PR (8817) - mean (1,206ms) : 1169, 1243
master - mean (1,214ms) : 1180, 1249
HttpMessageHandler (.NET Core 3.1)gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8817) - mean (290ms) : 284, 295
master - mean (291ms) : 283, 300
section Bailout
This PR (8817) - mean (290ms) : 284, 296
master - mean (293ms) : 285, 300
section CallTarget+Inlining+NGEN
This PR (8817) - mean (965ms) : 942, 987
master - mean (976ms) : 955, 997
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8817) - mean (281ms) : 274, 288
master - mean (286ms) : 280, 292
section Bailout
This PR (8817) - mean (282ms) : 276, 288
master - mean (284ms) : 276, 291
section CallTarget+Inlining+NGEN
This PR (8817) - mean (1,168ms) : 1127, 1210
master - mean (1,172ms) : 1121, 1223
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8817) - mean (281ms) : 276, 286
master - mean (282ms) : 276, 288
section Bailout
This PR (8817) - mean (282ms) : 277, 287
master - mean (281ms) : 276, 287
section CallTarget+Inlining+NGEN
This PR (8817) - mean (1,042ms) : 1002, 1081
master - mean (1,042ms) : 991, 1092
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
BenchmarksBenchmark execution time: 2026-06-23 11:32:02 Comparing candidate commit f8b703e in PR branch Found 0 performance improvements and 2 performance regressions! Performance is the same for 70 metrics, 0 unstable metrics, 61 known flaky benchmarks, 65 flaky benchmarks without significant changes.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ec21854b4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Document which debugger capture paths may execute customer code and add focused tests for current getter, exception, and collection capture behavior. Co-authored-by: Cursor <[email protected]>
Classify debugger reflection-loading risks and link the child PRs that address static member capture, IL token resolution, state-machine attributes, and customer-code execution policy. Co-authored-by: Cursor <[email protected]>
Co-authored-by: Cursor <[email protected]>
Co-authored-by: Cursor <[email protected]>
1ec2185 to
83db310
Compare
Summary of changes
AGENTS.mdso future agents and reviewers check it before changing debugger safety-sensitive paths.Reason for change
Define safety boundaries for debugger code running inside customer processes. Keeping the reflection audit, customer-code execution policy, and agent-facing guidance in one document gives reviewers one place to evaluate the current contract and the representative tests that lock it in.
Implementation details
This branch intentionally does not change capture behavior. The tests document that default object capture reads backing fields without invoking arbitrary getters, exception capture reads selected
System.Exceptionproperties, and supported collection serialization readsCountand enumerates under existing limits. The merged safety guide classifies related debugger reflection paths and defines when code may invoke getters, enumerators, exception overrides, attributes, orToString().Test coverage
DebuggerSnapshotCreatorTests.Policy_DebuggerSnapshotCreatorTestsRelated follow-up PRs: