[Dynamic Instrumentation] DEBUG-5317 fix snapshot stackoverflow in collection#8310
Conversation
BenchmarksBenchmark execution time: 2026-03-17 01:29:12 Comparing candidate commit cc2c348 in PR branch Found 12 performance improvements and 5 performance regressions! Performance is the same for 159 metrics, 16 unstable metrics. scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleSimpleBody net6.0
scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleSimpleBody netcoreapp3.1
scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorMoreComplexBody net6.0
scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorSimpleBody netcoreapp3.1
scenario:Benchmarks.Trace.Asm.AppSecEncoderBenchmark.EncodeLegacyArgs netcoreapp3.1
scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice net6.0
scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice netcoreapp3.1
scenario:Benchmarks.Trace.CharSliceBenchmark.OriginalCharSlice net6.0
scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark net6.0
scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark net6.0
scenario:Benchmarks.Trace.Log4netBenchmark.EnrichedLog netcoreapp3.1
scenario:Benchmarks.Trace.SingleSpanAspNetCoreBenchmark.SingleSpanAspNetCore netcoreapp3.1
scenario:Benchmarks.Trace.SpanBenchmark.StartFinishSpan net6.0
scenario:Benchmarks.Trace.SpanBenchmark.StartFinishTwoScopes net6.0
|
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8310) 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 (8310) - mean (75ms) : 72, 78
master - mean (75ms) : 73, 78
section Bailout
This PR (8310) - mean (80ms) : 77, 82
master - mean (80ms) : 77, 82
section CallTarget+Inlining+NGEN
This PR (8310) - mean (1,109ms) : 1055, 1164
master - mean (1,106ms) : 1061, 1150
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 (8310) - mean (117ms) : 113, 122
master - mean (119ms) : 115, 123
section Bailout
This PR (8310) - mean (118ms) : 116, 121
master - mean (120ms) : 117, 123
section CallTarget+Inlining+NGEN
This PR (8310) - mean (767ms) : 742, 792
master - mean (769ms) : 738, 800
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8310) - mean (104ms) : 101, 107
master - mean (105ms) : 102, 108
section Bailout
This PR (8310) - mean (105ms) : 103, 108
master - mean (106ms) : 103, 108
section CallTarget+Inlining+NGEN
This PR (8310) - mean (755ms) : 719, 790
master - mean (749ms) : 716, 782
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8310) - mean (104ms) : 101, 107
master - mean (104ms) : 101, 108
section Bailout
This PR (8310) - mean (105ms) : 103, 107
master - mean (106ms) : 102, 109
section CallTarget+Inlining+NGEN
This PR (8310) - mean (691ms) : 670, 713
master - mean (695ms) : 670, 719
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 (8310) - mean (194ms) : 189, 199
master - mean (194ms) : 191, 198
section Bailout
This PR (8310) - mean (196ms) : 194, 199
master - mean (198ms) : 194, 202
section CallTarget+Inlining+NGEN
This PR (8310) - mean (1,149ms) : 1103, 1196
master - mean (1,152ms) : 1106, 1199
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 (8310) - mean (277ms) : 272, 281
master - mean (279ms) : 275, 283
section Bailout
This PR (8310) - mean (277ms) : 272, 282
master - mean (278ms) : 274, 282
section CallTarget+Inlining+NGEN
This PR (8310) - mean (902ms) : 870, 935
master - mean (907ms) : 877, 937
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8310) - mean (270ms) : 266, 275
master - mean (272ms) : 265, 278
section Bailout
This PR (8310) - mean (270ms) : 266, 274
master - mean (271ms) : 267, 275
section CallTarget+Inlining+NGEN
This PR (8310) - mean (939ms) : 912, 966
master - mean (946ms) : 911, 980
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8310) - mean (270ms) : 263, 276
master - mean (269ms) : 264, 274
section Bailout
This PR (8310) - mean (271ms) : 267, 274
master - mean (269ms) : 264, 274
section CallTarget+Inlining+NGEN
This PR (8310) - mean (838ms) : 816, 860
master - mean (835ms) : 814, 857
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
a9eb98c to
cc2c348
Compare
Summary of changes
Prevent stack overflows in Dynamic Instrumentation snapshot serialization for cyclic collections.
Preserve existing collection depth semantics so collection elements do not consume an extra reference-depth level.
Add regression tests for collection depth behavior and cyclic collections.
Reason for change
Snapshot serialization could recurse indefinitely when serializing supported collections whose elements reference the collection (directly or indirectly), eventually crashing the process with a stack overflow.
Implementation details
Update
DebuggerSnapshotSerializer.SerializeEnumerableto track collections currently being serialized using per-serialization reference tracking.Stop serialization when the same collection instance is encountered again, emitting notCapturedReason: depth.
Keep MaxReferenceDepth enforcement on collection nodes.
Preserve existing snapshot behavior by serializing collection elements at the same logical depth as the collection itself.
Test coverage
Limits_SelfReferencingEnumerable_DoesNotStackOverflowLimits_IndirectCycleEnumerable_DoesNotStackOverflowLimits_Depth_AppliesToCollectionsAtMaxDepthLimits_CollectionElements_DoNotIncreaseDepth