[Dynamic Instrumentation] Omit capture data for condition evaluation errors#8728
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the Dynamic Instrumentation snapshot pipeline to treat condition-evaluation failures as “error-only” snapshots by suppressing capture serialization while still emitting snapshot metadata (e.g., stack frames and evaluationErrors). This aligns .NET behavior with the expected system-test semantics for condition errors, while preserving existing behavior for other expression errors.
Changes:
- Add a
HasConditionErrorflag toExpressionEvaluationResultand set it from condition-evaluation failure paths. - Update
ProbeProcessor/DebuggerSnapshotCreatorto skip capture-expression evaluation and suppress capture serialization when a condition error occurs, while keeping snapshot metadata and errors. - Add unit tests covering condition-error snapshots for method/line probes and processor finalization.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tracer/test/Datadog.Trace.Tests/Debugger/ProbeProcessorTests.cs | Adds coverage asserting condition-evaluation errors finalize without capture data. |
| tracer/test/Datadog.Trace.Tests/Debugger/DebuggerSnapshotCreatorTests.cs | Adds unit tests verifying method/line full snapshots omit capture data on condition errors. |
| tracer/src/Datadog.Trace/Debugger/Snapshots/DebuggerSnapshotCreator.cs | Introduces _omitCaptureData and gates capture writing/JSON container handling for condition-error snapshots. |
| tracer/src/Datadog.Trace/Debugger/Expressions/ProbeProcessor.cs | Skips capture-expression evaluation after condition errors; sets HasConditionError in some failure paths. |
| tracer/src/Datadog.Trace/Debugger/Expressions/ProbeExpressionEvaluator.cs | Marks HasConditionError when condition evaluation produces errors/exceptions. |
| tracer/src/Datadog.Trace/Debugger/Expressions/ExpressionEvaluationResult.cs | Adds HasConditionError to represent condition-evaluation failure distinctly. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This comment has been minimized.
This comment has been minimized.
955ba5d to
318407a
Compare
BenchmarksBenchmark execution time: 2026-06-03 17:17:00 Comparing candidate commit 0234b7b in PR branch Found 0 performance improvements and 1 performance regressions! Performance is the same for 71 metrics, 0 unstable metrics, 63 known flaky benchmarks, 63 flaky benchmarks without significant changes.
|
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8728) 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 (8728) - mean (76ms) : 71, 80
master - mean (76ms) : 72, 80
section Bailout
This PR (8728) - mean (80ms) : 76, 84
master - mean (79ms) : 75, 82
section CallTarget+Inlining+NGEN
This PR (8728) - mean (1,114ms) : 1061, 1167
master - mean (1,109ms) : 1054, 1164
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 (8728) - mean (117ms) : 112, 123
master - mean (115ms) : 108, 121
section Bailout
This PR (8728) - mean (116ms) : 114, 119
master - mean (115ms) : 112, 119
section CallTarget+Inlining+NGEN
This PR (8728) - mean (795ms) : 772, 818
master - mean (797ms) : 773, 821
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8728) - mean (101ms) : 97, 106
master - mean (101ms) : 98, 104
section Bailout
This PR (8728) - mean (105ms) : 101, 110
master - mean (107ms) : 102, 111
section CallTarget+Inlining+NGEN
This PR (8728) - mean (952ms) : 913, 990
master - mean (950ms) : 916, 983
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8728) - mean (99ms) : 94, 104
master - mean (100ms) : 98, 103
section Bailout
This PR (8728) - mean (101ms) : 97, 104
master - mean (101ms) : 99, 103
section CallTarget+Inlining+NGEN
This PR (8728) - mean (827ms) : 794, 861
master - mean (825ms) : 788, 862
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 (8728) - mean (200ms) : 196, 204
master - mean (201ms) : 197, 205
section Bailout
This PR (8728) - mean (204ms) : 200, 208
master - mean (204ms) : 199, 209
section CallTarget+Inlining+NGEN
This PR (8728) - mean (1,207ms) : 1159, 1254
master - mean (1,214ms) : 1173, 1256
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 (8728) - mean (288ms) : 281, 296
master - mean (292ms) : 285, 299
section Bailout
This PR (8728) - mean (288ms) : 282, 295
master - mean (291ms) : 285, 297
section CallTarget+Inlining+NGEN
This PR (8728) - mean (965ms) : 941, 989
master - mean (968ms) : 947, 989
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8728) - mean (282ms) : 276, 288
master - mean (280ms) : 274, 287
section Bailout
This PR (8728) - mean (280ms) : 274, 287
master - mean (279ms) : 274, 284
section CallTarget+Inlining+NGEN
This PR (8728) - mean (1,159ms) : 1119, 1198
master - mean (1,163ms) : 1120, 1207
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8728) - mean (279ms) : 273, 285
master - mean (280ms) : 274, 286
section Bailout
This PR (8728) - mean (279ms) : 275, 284
master - mean (280ms) : 273, 286
section CallTarget+Inlining+NGEN
This PR (8728) - mean (1,043ms) : 997, 1089
master - mean (1,042ms) : 1000, 1083
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Snapshots difference summaryThe following differences have been observed in committed snapshots. It is meant to help the reviewer. 1 occurrences of : - "captures": {
- "return": {
- "arguments": {
- "intArg": {
- "type": "Int32",
- "value": "1"
- },
- "this": {
- "type": "InvalidCondition"
- }
- },
- "locals": {
- "@return": {
- "type": "String",
- "value": "Argument: 1"
- }
- },
- "staticFields": {
- "Json": {
- "type": "String",
- "value": "{\r\n \"gt\": [\r\n \"undefined\",\r\n 2\r\n ]\r\n}"
- }
- }
- }
- },
+ "captures": {},
1 occurrences of : - "captures": {
- "return": {
- "arguments": {
- "intArg": {
- "type": "Int32",
- "value": "1"
- },
- "this": {
- "type": "UndefinedValue"
- }
- },
- "locals": {
- "@return": {
- "type": "String",
- "value": "Argument: 1"
- }
- },
- "staticFields": {
- "Json": {
- "type": "String",
- "value": "{\r\n \"gt\": [\r\n {\"ref\": \"undefined\"},\r\n 2\r\n ]\r\n}"
- }
- }
- }
- },
+ "captures": {},
|
| private List<EvaluationError>? _errors; | ||
| private string? _snapshotId; | ||
| private ObjectPool<MethodScopeMembers, MethodScopeMembersParameters> _scopeMembersPool; | ||
| private bool _omitCaptureData; |
There was a problem hiding this comment.
nit: Usually I refrain myself to use negative flag (disable, omit).
I prefer enable, captureData, useData, ...
Easier to reason about and read. Avoid brain shortcircuit 😁
3a1a88e to
c6532e0
Compare
c6532e0 to
0234b7b
Compare
Summary of changes
evaluationErrorsin error-only snapshots.ProbeProcessorcondition-error snapshots.Reason for change
Implementation details
HasConditionErrortoExpressionEvaluationResultand set it from condition evaluation failure paths.ProbeProcessoravoids evaluating capture expressions when a condition error has already occurred.DebuggerSnapshotCreatorsuppresses capture sections when handling condition errors, while still closing JSON containers correctly and writing stack/error metadata.Test coverage
DebuggerSnapshotCreateTests|ProbeProcessorTests