-
Notifications
You must be signed in to change notification settings - Fork 151
[IAST] Fix racing conditions in Dataflow #7838
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (7838) 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 (7838) - mean (77ms) : 68, 86
master - mean (75ms) : 71, 79
section Bailout
This PR (7838) - mean (81ms) : 74, 89
master - mean (79ms) : 74, 84
section CallTarget+Inlining+NGEN
This PR (7838) - mean (1,150ms) : 1048, 1253
master - mean (1,133ms) : 1053, 1212
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 (7838) - mean (118ms) : 109, 127
master - mean (118ms) : 112, 125
section Bailout
This PR (7838) - mean (119ms) : 110, 128
master - mean (121ms) : 113, 128
section CallTarget+Inlining+NGEN
This PR (7838) - mean (812ms) : 774, 851
master - mean (814ms) : 781, 848
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7838) - mean (105ms) : 97, 112
master - mean (108ms) : 102, 114
section Bailout
This PR (7838) - mean (106ms) : 98, 115
master - mean (106ms) : 100, 112
section CallTarget+Inlining+NGEN
This PR (7838) - mean (756ms) : 709, 802
master - mean (757ms) : 721, 792
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7838) - mean (104ms) : 97, 110
master - mean (104ms) : 99, 109
section Bailout
This PR (7838) - mean (105ms) : 96, 115
master - mean (105ms) : 99, 111
section CallTarget+Inlining+NGEN
This PR (7838) - mean (718ms) : 687, 750
master - mean (725ms) : 694, 757
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 (7838) - mean (200ms) : 193, 208
master - mean (192ms) : 188, 196
section Bailout
This PR (7838) - mean (201ms) : 197, 205
master - mean (195ms) : 193, 197
section CallTarget+Inlining+NGEN
This PR (7838) - mean (1,187ms) : 1112, 1262
master - mean (1,175ms) : 1102, 1248
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 (7838) - mean (278ms) : 271, 286
master - mean (279ms) : 271, 287
section Bailout
This PR (7838) - mean (280ms) : 273, 286
master - mean (278ms) : 274, 283
section CallTarget+Inlining+NGEN
This PR (7838) - mean (954ms) : 913, 995
master - mean (944ms) : 898, 991
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7838) - mean (272ms) : 266, 279
master - mean (280ms) : 272, 289
section Bailout
This PR (7838) - mean (271ms) : 267, 275
master - mean (277ms) : 269, 284
section CallTarget+Inlining+NGEN
This PR (7838) - mean (937ms) : 877, 996
master - mean (937ms) : 888, 987
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (7838) - mean (270ms) : 264, 275
master - mean (270ms) : 263, 277
section Bailout
This PR (7838) - mean (270ms) : 265, 275
master - mean (268ms) : 265, 271
section CallTarget+Inlining+NGEN
This PR (7838) - mean (867ms) : 838, 895
master - mean (859ms) : 840, 878
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This comment has been minimized.
This comment has been minimized.
BenchmarksBenchmarks Report for benchmark platform 🐌Benchmarks for #7838 compared to master:
The following thresholds were used for comparing the benchmark speeds:
Allocation changes below 0.5% are ignored. Benchmark detailsBenchmarks.Trace.ActivityBenchmark - Same speed ✔️ More allocations
|
| Benchmark | Base Allocated | Diff Allocated | Change | Change % |
|---|---|---|---|---|
| Benchmarks.Trace.ActivityBenchmark.StartStopWithChild‑net472 | 6.03 KB | 6.06 KB | 31 B | 0.51% |
| Benchmark | Base Allocated | Diff Allocated | Change | Change % |
|---|---|---|---|---|
| Benchmarks.Trace.ActivityBenchmark.StartStopWithChild‑net6.0 | 5.53 KB | 5.5 KB | -29 B | -0.52% |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | StartStopWithChild |
net6.0 | 11.1μs | 58.6ns | 293ns | 0 | 0 | 0 | 5.53 KB |
| master | StartStopWithChild |
netcoreapp3.1 | 14.1μs | 72.7ns | 341ns | 0 | 0 | 0 | 5.7 KB |
| master | StartStopWithChild |
net472 | 22.8μs | 123ns | 717ns | 1 | 0.335 | 0.112 | 6.03 KB |
| #7838 | StartStopWithChild |
net6.0 | 10.3μs | 57.1ns | 370ns | 0 | 0 | 0 | 5.5 KB |
| #7838 | StartStopWithChild |
netcoreapp3.1 | 13.8μs | 64.7ns | 259ns | 0 | 0 | 0 | 5.71 KB |
| #7838 | StartStopWithChild |
net472 | 22μs | 123ns | 855ns | 0.996 | 0.332 | 0.111 | 6.06 KB |
Benchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | WriteAndFlushEnrichedTraces |
net6.0 | 943μs | 143ns | 553ns | 0 | 0 | 0 | 2.71 KB |
| master | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 1.02ms | 263ns | 1.02μs | 0 | 0 | 0 | 2.7 KB |
| master | WriteAndFlushEnrichedTraces |
net472 | 1.23ms | 752ns | 2.91μs | 0 | 0 | 0 | 3.31 KB |
| #7838 | WriteAndFlushEnrichedTraces |
net6.0 | 927μs | 43.7ns | 164ns | 0 | 0 | 0 | 2.7 KB |
| #7838 | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 1.04ms | 579ns | 2.24μs | 0 | 0 | 0 | 2.7 KB |
| #7838 | WriteAndFlushEnrichedTraces |
net472 | 1.2ms | 650ns | 2.34μs | 0 | 0 | 0 | 3.31 KB |
Benchmarks.Trace.Asm.AppSecBodyBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | AllCycleSimpleBody |
net6.0 | 1.06μs | 5.91ns | 36.9ns | 0 | 0 | 0 | 1.22 KB |
| master | AllCycleSimpleBody |
netcoreapp3.1 | 1.4μs | 7.34ns | 35.2ns | 0 | 0 | 0 | 1.2 KB |
| master | AllCycleSimpleBody |
net472 | 1.04μs | 0.214ns | 0.773ns | 0.193 | 0 | 0 | 1.23 KB |
| master | AllCycleMoreComplexBody |
net6.0 | 7μs | 32.1ns | 129ns | 0 | 0 | 0 | 4.72 KB |
| master | AllCycleMoreComplexBody |
netcoreapp3.1 | 9μs | 33.8ns | 126ns | 0 | 0 | 0 | 4.62 KB |
| master | AllCycleMoreComplexBody |
net472 | 7.65μs | 2.35ns | 8.8ns | 0.727 | 0 | 0 | 4.74 KB |
| master | ObjectExtractorSimpleBody |
net6.0 | 319ns | 1.59ns | 6.57ns | 0 | 0 | 0 | 280 B |
| master | ObjectExtractorSimpleBody |
netcoreapp3.1 | 394ns | 1.95ns | 8.06ns | 0 | 0 | 0 | 272 B |
| master | ObjectExtractorSimpleBody |
net472 | 294ns | 0.0443ns | 0.172ns | 0.0444 | 0 | 0 | 281 B |
| master | ObjectExtractorMoreComplexBody |
net6.0 | 6.24μs | 33.3ns | 173ns | 0 | 0 | 0 | 3.78 KB |
| master | ObjectExtractorMoreComplexBody |
netcoreapp3.1 | 7.79μs | 36.9ns | 157ns | 0 | 0 | 0 | 3.69 KB |
| master | ObjectExtractorMoreComplexBody |
net472 | 6.74μs | 7.45ns | 28.9ns | 0.572 | 0 | 0 | 3.8 KB |
| #7838 | AllCycleSimpleBody |
net6.0 | 1.06μs | 5.6ns | 29.6ns | 0 | 0 | 0 | 1.22 KB |
| #7838 | AllCycleSimpleBody |
netcoreapp3.1 | 1.45μs | 1.19ns | 4.45ns | 0 | 0 | 0 | 1.2 KB |
| #7838 | AllCycleSimpleBody |
net472 | 1.03μs | 0.348ns | 1.35ns | 0.194 | 0 | 0 | 1.23 KB |
| #7838 | AllCycleMoreComplexBody |
net6.0 | 7.12μs | 37.2ns | 134ns | 0 | 0 | 0 | 4.72 KB |
| #7838 | AllCycleMoreComplexBody |
netcoreapp3.1 | 8.89μs | 33.9ns | 131ns | 0 | 0 | 0 | 4.62 KB |
| #7838 | AllCycleMoreComplexBody |
net472 | 7.61μs | 7.67ns | 29.7ns | 0.721 | 0 | 0 | 4.74 KB |
| #7838 | ObjectExtractorSimpleBody |
net6.0 | 332ns | 1.82ns | 10.9ns | 0 | 0 | 0 | 280 B |
| #7838 | ObjectExtractorSimpleBody |
netcoreapp3.1 | 400ns | 2.04ns | 8.14ns | 0 | 0 | 0 | 272 B |
| #7838 | ObjectExtractorSimpleBody |
net472 | 305ns | 0.0121ns | 0.0438ns | 0.0445 | 0 | 0 | 281 B |
| #7838 | ObjectExtractorMoreComplexBody |
net6.0 | 6.24μs | 29.3ns | 113ns | 0 | 0 | 0 | 3.78 KB |
| #7838 | ObjectExtractorMoreComplexBody |
netcoreapp3.1 | 7.78μs | 39.7ns | 154ns | 0 | 0 | 0 | 3.69 KB |
| #7838 | ObjectExtractorMoreComplexBody |
net472 | 6.73μs | 1.18ns | 4.42ns | 0.572 | 0 | 0 | 3.8 KB |
Benchmarks.Trace.Asm.AppSecEncoderBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | EncodeArgs |
net6.0 | 76.4μs | 78.4ns | 303ns | 0 | 0 | 0 | 32.4 KB |
| master | EncodeArgs |
netcoreapp3.1 | 96.8μs | 297ns | 1.15μs | 0 | 0 | 0 | 32.4 KB |
| master | EncodeArgs |
net472 | 111μs | 14.2ns | 53.3ns | 5.01 | 0 | 0 | 32.5 KB |
| master | EncodeLegacyArgs |
net6.0 | 145μs | 151ns | 587ns | 0 | 0 | 0 | 2.15 KB |
| master | EncodeLegacyArgs |
netcoreapp3.1 | 195μs | 197ns | 763ns | 0 | 0 | 0 | 2.14 KB |
| master | EncodeLegacyArgs |
net472 | 265μs | 20ns | 77.5ns | 0 | 0 | 0 | 2.16 KB |
| #7838 | EncodeArgs |
net6.0 | 75.8μs | 278ns | 1.04μs | 0 | 0 | 0 | 32.4 KB |
| #7838 | EncodeArgs |
netcoreapp3.1 | 96.5μs | 377ns | 1.46μs | 0 | 0 | 0 | 32.4 KB |
| #7838 | EncodeArgs |
net472 | 110μs | 10.8ns | 42ns | 4.94 | 0 | 0 | 32.51 KB |
| #7838 | EncodeLegacyArgs |
net6.0 | 148μs | 246ns | 952ns | 0 | 0 | 0 | 2.15 KB |
| #7838 | EncodeLegacyArgs |
netcoreapp3.1 | 197μs | 226ns | 877ns | 0 | 0 | 0 | 2.14 KB |
| #7838 | EncodeLegacyArgs |
net472 | 264μs | 33.7ns | 126ns | 0 | 0 | 0 | 2.16 KB |
Benchmarks.Trace.Asm.AppSecWafBenchmark - Slower ⚠️ Same allocations ✔️
Slower ⚠️ in #7838
Benchmark
diff/base
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmarkWithAttack‑netcoreapp3.1
2.445
301,427.21
737,132.09
| Benchmark | diff/base | Base Median (ns) | Diff Median (ns) | Modality |
|---|---|---|---|---|
| Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmarkWithAttack‑netcoreapp3.1 | 2.445 | 301,427.21 | 737,132.09 |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | RunWafRealisticBenchmark |
net6.0 | 390μs | 67.1ns | 242ns | 0 | 0 | 0 | 4.55 KB |
| master | RunWafRealisticBenchmark |
netcoreapp3.1 | 413μs | 661ns | 2.56μs | 0 | 0 | 0 | 4.48 KB |
| master | RunWafRealisticBenchmark |
net472 | 428μs | 51.2ns | 198ns | 0 | 0 | 0 | 4.66 KB |
| master | RunWafRealisticBenchmarkWithAttack |
net6.0 | 285μs | 77.7ns | 301ns | 0 | 0 | 0 | 2.24 KB |
| master | RunWafRealisticBenchmarkWithAttack |
netcoreapp3.1 | 302μs | 168ns | 581ns | 0 | 0 | 0 | 2.22 KB |
| master | RunWafRealisticBenchmarkWithAttack |
net472 | 311μs | 24.6ns | 95.2ns | 0 | 0 | 0 | 2.29 KB |
| #7838 | RunWafRealisticBenchmark |
net6.0 | 396μs | 75.6ns | 283ns | 0 | 0 | 0 | 4.55 KB |
| #7838 | RunWafRealisticBenchmark |
netcoreapp3.1 | 416μs | 81.8ns | 306ns | 0 | 0 | 0 | 4.48 KB |
| #7838 | RunWafRealisticBenchmark |
net472 | 431μs | 69.6ns | 269ns | 0 | 0 | 0 | 4.68 KB |
| #7838 | RunWafRealisticBenchmarkWithAttack |
net6.0 | 283μs | 39.2ns | 152ns | 0 | 0 | 0 | 2.24 KB |
| #7838 | RunWafRealisticBenchmarkWithAttack |
netcoreapp3.1 | 671μs | 14.1μs | 141μs | 0 | 0 | 0 | 2.22 KB |
| #7838 | RunWafRealisticBenchmarkWithAttack |
net472 | 310μs | 143ns | 554ns | 0 | 0 | 0 | 2.29 KB |
Benchmarks.Trace.AspNetCoreBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | SendRequest |
net6.0 | 60.8μs | 81.4ns | 315ns | 0 | 0 | 0 | 14.58 KB |
| master | SendRequest |
netcoreapp3.1 | 71.5μs | 102ns | 395ns | 0 | 0 | 0 | 17.42 KB |
| master | SendRequest |
net472 | 0.00854ns | 0.00243ns | 0.00943ns | 0 | 0 | 0 | 0 b |
| #7838 | SendRequest |
net6.0 | 60.6μs | 93.4ns | 337ns | 0 | 0 | 0 | 14.52 KB |
| #7838 | SendRequest |
netcoreapp3.1 | 71.4μs | 349ns | 1.4μs | 0 | 0 | 0 | 17.42 KB |
| #7838 | SendRequest |
net472 | 0.014ns | 0.00302ns | 0.0117ns | 0 | 0 | 0 | 0 b |
Benchmarks.Trace.CharSliceBenchmark - Slower ⚠️ More allocations ⚠️
Slower ⚠️ in #7838
Benchmark
diff/base
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice‑net6.0
1.112
1,344,390.62
1,494,760.07
More allocations ⚠️ in #7838
Benchmark
Base Allocated
Diff Allocated
Change
Change %
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool‑net6.0
2 B
4 B
2 B
100.00%
Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice‑net6.0
4 B
7 B
3 B
75.00%
| Benchmark | diff/base | Base Median (ns) | Diff Median (ns) | Modality |
|---|---|---|---|---|
| Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice‑net6.0 | 1.112 | 1,344,390.62 | 1,494,760.07 |
| Benchmark | Base Allocated | Diff Allocated | Change | Change % |
|---|---|---|---|---|
| Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool‑net6.0 | 2 B | 4 B | 2 B | 100.00% |
| Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice‑net6.0 | 4 B | 7 B | 3 B | 75.00% |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | OriginalCharSlice |
net6.0 | 1.9ms | 4.85μs | 18.1μs | 0 | 0 | 0 | 640 KB |
| master | OriginalCharSlice |
netcoreapp3.1 | 2.11ms | 7.29μs | 27.3μs | 0 | 0 | 0 | 640 KB |
| master | OriginalCharSlice |
net472 | 2.66ms | 146ns | 526ns | 100 | 0 | 0 | 641.95 KB |
| master | OptimizedCharSlice |
net6.0 | 1.34ms | 240ns | 898ns | 0 | 0 | 0 | 4 B |
| master | OptimizedCharSlice |
netcoreapp3.1 | 1.73ms | 2.16μs | 8.38μs | 0 | 0 | 0 | 1 B |
| master | OptimizedCharSlice |
net472 | 1.93ms | 1.78μs | 6.91μs | 0 | 0 | 0 | 0 b |
| master | OptimizedCharSliceWithPool |
net6.0 | 801μs | 77.9ns | 302ns | 0 | 0 | 0 | 2 B |
| master | OptimizedCharSliceWithPool |
netcoreapp3.1 | 852μs | 232ns | 900ns | 0 | 0 | 0 | 0 b |
| master | OptimizedCharSliceWithPool |
net472 | 1.14ms | 87.8ns | 329ns | 0 | 0 | 0 | 0 b |
| #7838 | OriginalCharSlice |
net6.0 | 1.93ms | 704ns | 2.73μs | 0 | 0 | 0 | 640.01 KB |
| #7838 | OriginalCharSlice |
netcoreapp3.1 | 2.14ms | 5.55μs | 20.8μs | 0 | 0 | 0 | 640 KB |
| #7838 | OriginalCharSlice |
net472 | 2.66ms | 118ns | 426ns | 100 | 0 | 0 | 641.95 KB |
| #7838 | OptimizedCharSlice |
net6.0 | 1.49ms | 200ns | 776ns | 0 | 0 | 0 | 7 B |
| #7838 | OptimizedCharSlice |
netcoreapp3.1 | 1.71ms | 191ns | 738ns | 0 | 0 | 0 | 1 B |
| #7838 | OptimizedCharSlice |
net472 | 1.97ms | 272ns | 1.05μs | 0 | 0 | 0 | 0 b |
| #7838 | OptimizedCharSliceWithPool |
net6.0 | 801μs | 97.1ns | 376ns | 0 | 0 | 0 | 4 B |
| #7838 | OptimizedCharSliceWithPool |
netcoreapp3.1 | 840μs | 144ns | 556ns | 0 | 0 | 0 | 0 b |
| #7838 | OptimizedCharSliceWithPool |
net472 | 1.14ms | 104ns | 402ns | 0 | 0 | 0 | 0 b |
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark - Faster 🎉 More allocations ⚠️
Faster 🎉 in #7838
Benchmark
base/diff
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net472
1.145
964,420.98
842,134.58
More allocations ⚠️ in #7838
Benchmark
Base Allocated
Diff Allocated
Change
Change %
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑netcoreapp3.1
41.78 KB
42.21 KB
436 B
1.04%
Fewer allocations 🎉 in #7838
Benchmark
Base Allocated
Diff Allocated
Change
Change %
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net472
56.47 KB
56.15 KB
-317 B
-0.56%
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net6.0
42.2 KB
41.73 KB
-471 B
-1.12%
| Benchmark | base/diff | Base Median (ns) | Diff Median (ns) | Modality |
|---|---|---|---|---|
| Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net472 | 1.145 | 964,420.98 | 842,134.58 |
| Benchmark | Base Allocated | Diff Allocated | Change | Change % |
|---|---|---|---|---|
| Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑netcoreapp3.1 | 41.78 KB | 42.21 KB | 436 B | 1.04% |
| Benchmark | Base Allocated | Diff Allocated | Change | Change % |
|---|---|---|---|---|
| Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net472 | 56.47 KB | 56.15 KB | -317 B | -0.56% |
| Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net6.0 | 42.2 KB | 41.73 KB | -471 B | -1.12% |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | WriteAndFlushEnrichedTraces |
net6.0 | 629μs | 1.76μs | 6.33μs | 0 | 0 | 0 | 42.2 KB |
| master | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 719μs | 4.14μs | 31.5μs | 0 | 0 | 0 | 41.78 KB |
| master | WriteAndFlushEnrichedTraces |
net472 | 964μs | 3.39μs | 13.1μs | 8.93 | 0 | 0 | 56.47 KB |
| #7838 | WriteAndFlushEnrichedTraces |
net6.0 | 642μs | 3.37μs | 17.5μs | 0 | 0 | 0 | 41.73 KB |
| #7838 | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 734μs | 620ns | 2.4μs | 0 | 0 | 0 | 42.21 KB |
| #7838 | WriteAndFlushEnrichedTraces |
net472 | 844μs | 2.01μs | 7.77μs | 8.33 | 0 | 0 | 56.15 KB |
Benchmarks.Trace.DbCommandBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | ExecuteNonQuery |
net6.0 | 1.91μs | 7.99ns | 30.9ns | 0 | 0 | 0 | 1.02 KB |
| master | ExecuteNonQuery |
netcoreapp3.1 | 2.7μs | 7.56ns | 27.3ns | 0 | 0 | 0 | 1.02 KB |
| master | ExecuteNonQuery |
net472 | 2.83μs | 1.7ns | 6.38ns | 0.156 | 0.0142 | 0 | 987 B |
| #7838 | ExecuteNonQuery |
net6.0 | 1.91μs | 5.83ns | 22.6ns | 0 | 0 | 0 | 1.02 KB |
| #7838 | ExecuteNonQuery |
netcoreapp3.1 | 2.64μs | 10.8ns | 40.2ns | 0 | 0 | 0 | 1.02 KB |
| #7838 | ExecuteNonQuery |
net472 | 2.81μs | 3.83ns | 14.8ns | 0.153 | 0.0139 | 0 | 987 B |
Benchmarks.Trace.ElasticsearchBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | CallElasticsearch |
net6.0 | 1.72μs | 0.689ns | 2.58ns | 0 | 0 | 0 | 1.03 KB |
| master | CallElasticsearch |
netcoreapp3.1 | 2.31μs | 10.6ns | 41.1ns | 0 | 0 | 0 | 1.03 KB |
| master | CallElasticsearch |
net472 | 3.59μs | 2.37ns | 9.17ns | 0.16 | 0 | 0 | 1.04 KB |
| master | CallElasticsearchAsync |
net6.0 | 1.81μs | 7ns | 27.1ns | 0 | 0 | 0 | 1.01 KB |
| master | CallElasticsearchAsync |
netcoreapp3.1 | 2.41μs | 8.22ns | 30.7ns | 0 | 0 | 0 | 1.08 KB |
| master | CallElasticsearchAsync |
net472 | 3.72μs | 5.41ns | 21ns | 0.167 | 0 | 0 | 1.1 KB |
| #7838 | CallElasticsearch |
net6.0 | 1.67μs | 8.46ns | 37.8ns | 0 | 0 | 0 | 1.03 KB |
| #7838 | CallElasticsearch |
netcoreapp3.1 | 2.22μs | 7.83ns | 30.3ns | 0 | 0 | 0 | 1.03 KB |
| #7838 | CallElasticsearch |
net472 | 3.48μs | 1.46ns | 5.45ns | 0.157 | 0 | 0 | 1.04 KB |
| #7838 | CallElasticsearchAsync |
net6.0 | 1.92μs | 9.57ns | 39.5ns | 0 | 0 | 0 | 1.01 KB |
| #7838 | CallElasticsearchAsync |
netcoreapp3.1 | 2.34μs | 9.94ns | 35.9ns | 0 | 0 | 0 | 1.08 KB |
| #7838 | CallElasticsearchAsync |
net472 | 3.61μs | 3.45ns | 13.4ns | 0.163 | 0 | 0 | 1.1 KB |
Benchmarks.Trace.GraphQLBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | ExecuteAsync |
net6.0 | 1.91μs | 6.61ns | 25.6ns | 0 | 0 | 0 | 952 B |
| master | ExecuteAsync |
netcoreapp3.1 | 2.44μs | 8.59ns | 33.3ns | 0 | 0 | 0 | 952 B |
| master | ExecuteAsync |
net472 | 2.61μs | 1.24ns | 4.3ns | 0.144 | 0 | 0 | 915 B |
| #7838 | ExecuteAsync |
net6.0 | 1.8μs | 7.76ns | 30.1ns | 0 | 0 | 0 | 952 B |
| #7838 | ExecuteAsync |
netcoreapp3.1 | 2.45μs | 7.25ns | 28.1ns | 0 | 0 | 0 | 952 B |
| #7838 | ExecuteAsync |
net472 | 2.61μs | 5.87ns | 22.7ns | 0.144 | 0 | 0 | 915 B |
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | SendAsync |
net6.0 | 7.01μs | 24.1ns | 93.3ns | 0 | 0 | 0 | 2.36 KB |
| master | SendAsync |
netcoreapp3.1 | 8.55μs | 12.7ns | 47.6ns | 0 | 0 | 0 | 2.9 KB |
| master | SendAsync |
net472 | 12.3μs | 8.09ns | 30.3ns | 0.492 | 0 | 0 | 3.18 KB |
| #7838 | SendAsync |
net6.0 | 6.89μs | 6.89ns | 25.8ns | 0 | 0 | 0 | 2.36 KB |
| #7838 | SendAsync |
netcoreapp3.1 | 8.67μs | 17.5ns | 67.6ns | 0 | 0 | 0 | 2.9 KB |
| #7838 | SendAsync |
net472 | 12.1μs | 6.77ns | 25.3ns | 0.478 | 0 | 0 | 3.18 KB |
Benchmarks.Trace.Iast.StringAspectsBenchmark - Same speed ✔️ More allocations ⚠️
More allocations ⚠️ in #7838
Benchmark
Base Allocated
Diff Allocated
Change
Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0
257.14 KB
277.31 KB
20.17 KB
7.84%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑netcoreapp3.1
42.73 KB
45.5 KB
2.78 KB
6.50%
Fewer allocations 🎉 in #7838
Benchmark
Base Allocated
Diff Allocated
Change
Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑net6.0
44.1 KB
43.71 KB
-392 B
-0.89%
| Benchmark | Base Allocated | Diff Allocated | Change | Change % |
|---|---|---|---|---|
| Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0 | 257.14 KB | 277.31 KB | 20.17 KB | 7.84% |
| Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑netcoreapp3.1 | 42.73 KB | 45.5 KB | 2.78 KB | 6.50% |
| Benchmark | Base Allocated | Diff Allocated | Change | Change % |
|---|---|---|---|---|
| Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑net6.0 | 44.1 KB | 43.71 KB | -392 B | -0.89% |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | StringConcatBenchmark |
net6.0 | 44μs | 237ns | 1.28μs | 0 | 0 | 0 | 44.1 KB |
| master | StringConcatBenchmark |
netcoreapp3.1 | 49.6μs | 289ns | 2.33μs | 0 | 0 | 0 | 42.73 KB |
| master | StringConcatBenchmark |
net472 | 57.1μs | 251ns | 973ns | 0 | 0 | 0 | 57.34 KB |
| master | StringConcatAspectBenchmark |
net6.0 | 481μs | 1.93μs | 8.84μs | 0 | 0 | 0 | 257.14 KB |
| master | StringConcatAspectBenchmark |
netcoreapp3.1 | 553μs | 2.35μs | 9.1μs | 0 | 0 | 0 | 276.95 KB |
| master | StringConcatAspectBenchmark |
net472 | 409μs | 2.19μs | 11.2μs | 0 | 0 | 0 | 278.53 KB |
| #7838 | StringConcatBenchmark |
net6.0 | 42.2μs | 222ns | 1.13μs | 0 | 0 | 0 | 43.71 KB |
| #7838 | StringConcatBenchmark |
netcoreapp3.1 | 50.8μs | 332ns | 3.13μs | 0 | 0 | 0 | 45.5 KB |
| #7838 | StringConcatBenchmark |
net472 | 57.6μs | 280ns | 1.12μs | 0 | 0 | 0 | 57.34 KB |
| #7838 | StringConcatAspectBenchmark |
net6.0 | 471μs | 1.98μs | 7.93μs | 0 | 0 | 0 | 277.31 KB |
| #7838 | StringConcatAspectBenchmark |
netcoreapp3.1 | 528μs | 1.29μs | 4.46μs | 0 | 0 | 0 | 276.98 KB |
| #7838 | StringConcatAspectBenchmark |
net472 | 408μs | 2.25μs | 13.5μs | 0 | 0 | 0 | 278.53 KB |
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | EnrichedLog |
net6.0 | 2.6μs | 12.7ns | 53.7ns | 0 | 0 | 0 | 1.7 KB |
| master | EnrichedLog |
netcoreapp3.1 | 3.56μs | 16.7ns | 64.9ns | 0 | 0 | 0 | 1.7 KB |
| master | EnrichedLog |
net472 | 3.91μs | 4.49ns | 17.4ns | 0.253 | 0 | 0 | 1.64 KB |
| #7838 | EnrichedLog |
net6.0 | 2.64μs | 12.8ns | 49.4ns | 0 | 0 | 0 | 1.7 KB |
| #7838 | EnrichedLog |
netcoreapp3.1 | 3.66μs | 17.9ns | 71.6ns | 0 | 0 | 0 | 1.7 KB |
| #7838 | EnrichedLog |
net472 | 3.82μs | 3.11ns | 12ns | 0.248 | 0 | 0 | 1.64 KB |
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | EnrichedLog |
net6.0 | 121μs | 55ns | 198ns | 0 | 0 | 0 | 4.31 KB |
| master | EnrichedLog |
netcoreapp3.1 | 126μs | 38.9ns | 135ns | 0 | 0 | 0 | 4.31 KB |
| master | EnrichedLog |
net472 | 166μs | 31.1ns | 112ns | 0 | 0 | 0 | 4.52 KB |
| #7838 | EnrichedLog |
net6.0 | 124μs | 76.5ns | 265ns | 0 | 0 | 0 | 4.31 KB |
| #7838 | EnrichedLog |
netcoreapp3.1 | 127μs | 156ns | 582ns | 0 | 0 | 0 | 4.31 KB |
| #7838 | EnrichedLog |
net472 | 167μs | 59ns | 229ns | 0 | 0 | 0 | 4.52 KB |
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | EnrichedLog |
net6.0 | 5.01μs | 2.82ns | 10.9ns | 0 | 0 | 0 | 2.26 KB |
| master | EnrichedLog |
netcoreapp3.1 | 6.75μs | 14.7ns | 55.2ns | 0 | 0 | 0 | 2.26 KB |
| master | EnrichedLog |
net472 | 7.56μs | 5.86ns | 22.7ns | 0.302 | 0 | 0 | 2.08 KB |
| #7838 | EnrichedLog |
net6.0 | 4.98μs | 19ns | 71ns | 0 | 0 | 0 | 2.26 KB |
| #7838 | EnrichedLog |
netcoreapp3.1 | 6.99μs | 11.5ns | 44.5ns | 0 | 0 | 0 | 2.26 KB |
| #7838 | EnrichedLog |
net472 | 7.46μs | 5.53ns | 21.4ns | 0.297 | 0 | 0 | 2.08 KB |
Benchmarks.Trace.RedisBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | SendReceive |
net6.0 | 1.98μs | 10.2ns | 50.8ns | 0 | 0 | 0 | 1.2 KB |
| master | SendReceive |
netcoreapp3.1 | 2.65μs | 11.1ns | 42.9ns | 0 | 0 | 0 | 1.2 KB |
| master | SendReceive |
net472 | 3.21μs | 5.15ns | 19.9ns | 0.176 | 0 | 0 | 1.2 KB |
| #7838 | SendReceive |
net6.0 | 2.07μs | 2.14ns | 8.3ns | 0 | 0 | 0 | 1.2 KB |
| #7838 | SendReceive |
netcoreapp3.1 | 2.59μs | 10.2ns | 39.3ns | 0 | 0 | 0 | 1.2 KB |
| #7838 | SendReceive |
net472 | 3.09μs | 2.7ns | 10.4ns | 0.184 | 0 | 0 | 1.2 KB |
Benchmarks.Trace.SerilogBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | EnrichedLog |
net6.0 | 4.21μs | 2.82ns | 10.5ns | 0 | 0 | 0 | 1.58 KB |
| master | EnrichedLog |
netcoreapp3.1 | 5.65μs | 14.4ns | 55.9ns | 0 | 0 | 0 | 1.63 KB |
| master | EnrichedLog |
net472 | 6.44μs | 4.44ns | 16ns | 0.32 | 0 | 0 | 2.03 KB |
| #7838 | EnrichedLog |
net6.0 | 4.33μs | 1.99ns | 7.44ns | 0 | 0 | 0 | 1.58 KB |
| #7838 | EnrichedLog |
netcoreapp3.1 | 5.58μs | 17.4ns | 67.4ns | 0 | 0 | 0 | 1.63 KB |
| #7838 | EnrichedLog |
net472 | 6.68μs | 6.12ns | 23.7ns | 0.299 | 0 | 0 | 2.03 KB |
Benchmarks.Trace.SpanBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | StartFinishSpan |
net6.0 | 761ns | 3.94ns | 19.7ns | 0 | 0 | 0 | 576 B |
| master | StartFinishSpan |
netcoreapp3.1 | 978ns | 0.909ns | 3.52ns | 0 | 0 | 0 | 576 B |
| master | StartFinishSpan |
net472 | 978ns | 0.335ns | 1.21ns | 0.0882 | 0 | 0 | 578 B |
| master | StartFinishScope |
net6.0 | 908ns | 4.68ns | 22.4ns | 0 | 0 | 0 | 696 B |
| master | StartFinishScope |
netcoreapp3.1 | 1.18μs | 5.86ns | 25.6ns | 0 | 0 | 0 | 696 B |
| master | StartFinishScope |
net472 | 1.19μs | 0.243ns | 0.875ns | 0.0995 | 0 | 0 | 658 B |
| #7838 | StartFinishSpan |
net6.0 | 776ns | 4.03ns | 20.6ns | 0 | 0 | 0 | 576 B |
| #7838 | StartFinishSpan |
netcoreapp3.1 | 983ns | 5.26ns | 28.8ns | 0 | 0 | 0 | 576 B |
| #7838 | StartFinishSpan |
net472 | 952ns | 0.29ns | 1.12ns | 0.0908 | 0 | 0 | 578 B |
| #7838 | StartFinishScope |
net6.0 | 918ns | 1.77ns | 6.85ns | 0 | 0 | 0 | 696 B |
| #7838 | StartFinishScope |
netcoreapp3.1 | 1.17μs | 5.87ns | 27.5ns | 0 | 0 | 0 | 696 B |
| #7838 | StartFinishScope |
net472 | 1.19μs | 0.657ns | 2.54ns | 0.101 | 0 | 0 | 658 B |
Benchmarks.Trace.TraceAnnotationsBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | RunOnMethodBegin |
net6.0 | 1.02μs | 5.68ns | 33.6ns | 0 | 0 | 0 | 696 B |
| master | RunOnMethodBegin |
netcoreapp3.1 | 1.44μs | 5.48ns | 21.2ns | 0 | 0 | 0 | 696 B |
| master | RunOnMethodBegin |
net472 | 1.56μs | 0.988ns | 3.83ns | 0.101 | 0 | 0 | 658 B |
| #7838 | RunOnMethodBegin |
net6.0 | 1.04μs | 5.46ns | 31.4ns | 0 | 0 | 0 | 696 B |
| #7838 | RunOnMethodBegin |
netcoreapp3.1 | 1.4μs | 7.03ns | 31.5ns | 0 | 0 | 0 | 696 B |
| #7838 | RunOnMethodBegin |
net472 | 1.46μs | 2.29ns | 8.89ns | 0.102 | 0 | 0 | 658 B |
| if (!IsInitialized()) | ||
| { | ||
| _initialized = true; | ||
| SetInitialized(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silly question, but could this also be part of the problem? 🤔
We set initialized = true here before we've finished the initialization. That means that all the other places where we do if (!IsInitialized()) and bail out will stop bailing 🤔 Also, we don't have a CSGUARD in here, should we?
I feel like we probably need something more like this?
CSGUARD(_cs);
if (!IsInitialized())
{
// Do all the other work in the if block
SetInitialized(true);
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes I do think you need to guard in this one as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main problem is here, in LoadAspects, and this function is the one that has to be well covered. _isInitialized should be set to true as the last thing done here, not in the begining of the function.
| HRESULT Dataflow::AppDomainShutdown(AppDomainID appDomainId) | ||
| { | ||
| if (!_initialized) | ||
| CSGUARD(_cs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to use double checking here to avoid contention? I'm not sure it's a big problem for AppDomainShutdown really, and how often would we not be initialized? 🤔
// Initial check outside the lock
if (!IsInitialized())
{
return S_OK;
}
CSGUARD(_cs);
// Double check inside the lock
if (!IsInitialized())
{
return S_OK;
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we add the guard for each IsInitialized() call we should consider to just use a normal bool instead of the atomic bool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not going to find the situation where a threar reads true while it has been set to false. The problem is the oposite, in initialization. IMO the whole thing could be solved with deferring the set to true in _isInitialized to the end of the LoadAspects function.
| HRESULT Dataflow::ModuleLoaded(ModuleID moduleId, ModuleInfo** pModuleInfo) | ||
| { | ||
| if (!_initialized) | ||
| if (!IsInitialized()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still has the CSGUARD after the IsInitialized() check (because it takes the lock in GetModuleInfo... should we move this check inside GetModuleInfo() instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetModuleInfo() already checks for that, this is just an early check.
| bool Dataflow::IsInlineEnabled(ModuleID calleeModuleId, mdToken calleeMethodId) | ||
| { | ||
| if (!_initialized) | ||
| if (!IsInitialized()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like there's a bunch of places here without the guards... is that safe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is safe as long as we dont perform sensitive operations. In this case, IsInitialized() is already safe because we are using an atomic bool and we will recheck that later in a locked envirinment.
Methods like IsInlineEnabled(), JITProcessMethod(), and JITCompilationStarted() check IsInitialized() outside locks because the atomic read itself is safe, they perform no "sensitive operations" (directly accessing shared state _modules, _appDomains, _moduleAspects) and the real protection is at the leaf level. When these methods call GetModuleInfo() or GetAppDomain(), those methods acquire the lock first, check IsInitialized() inside the lock (TOCTOU-safe) and only then access shared maps.
gleocadie
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| Dataflow::~Dataflow() | ||
| { | ||
| _initialized = false; | ||
| CSGUARD(_cs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dataflow is destroyed on profiler unload and this is the only place where _initialized is set to false. This CS is unnecessary (although does not hurt).
daniel-romano-DD
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is overkill for the real crash reason. A calmer look and a different approach is needed.
Summary of changes
This PR fixes multi-threading issues in Dataflow that could lead to corruption of the internal std::map structures (_modules, _appDomains, _moduleAspects) and subsequent crashes inside MSVC STL (_Tree::_Find_lower_bound). These issues were observed as flaky CI failures on Windows x86, manifesting as:
Inspecting the dump, we get the following stack:
This is where the exception was thrown, but not necessarily where the problem is. The map could get corrupted earlier and later the exception thrown in some internal checks.
Root Causes
The Dataflow instance is accessed from multiple CLR profiler callbacks (
JITCachedFunctionSearchStarted,JITCompilationStarted, module load/unload, ReJIT), which execute on various .NET threads. While most code paths synchronize access to shared maps via_cs, several critical issues existed:1. Unsynchronized Destructor
Dataflow::~Dataflow()modified_modules,_appDomains, and_moduleAspectswithout holding_cs, allowing races where:GetModuleInfo()under the lock2. Time-of-Check-Time-of-Use (TOCTOU) Race Conditions
Multiple methods checked
_initializedoutside the critical section, then accessed shared maps inside the lock:GetAppDomain(),GetModuleInfo(),GetAspectsModule()AppDomainShutdown(),ModuleUnloaded()GetAspects()This created a race window where:
IsInitialized()→ returns TRUE (no lock held)_initialized = false, destroys all maps3. Non-Atomic
_initializedFlag_initializedwas a plainboolaccessed concurrently without synchronization, causing:4. Unsynchronized Map Access in LoadAspects()
LoadAspects()cleared_moduleAspectswithout locking.Fixes Included in This PR
1. Eliminate TOCTOU Races - Move Checks Inside Critical Sections
All methods that directly access shared maps now check
IsInitialized()inside theCSGUARD(_cs)lock:~Dataflow()- Acquires lock first, then sets flag and destroys maps atomicallyGetAppDomain()- Lock → check → accessGetModuleInfo()- Lock → check → accessAppDomainShutdown()- Lock → check → accessModuleUnloaded()- Lock → check → accessGetAspects()- Lock → check → accessThis ensures that once the destructor sets
_initialized = falseinside the lock, no other thread can proceed past the check to access destroyed state.Before (vulnerable):
After (safe):
2. Atomic
_initializedwith Proper Memory OrderingChanged
_initializedfrombooltostd::atomic<bool>with:memory_order_acquirefor loads (inIsInitialized())memory_order_releasefor stores (inSetInitialized())This ensures:
_initialized == false, it's guaranteed to see all prior writes made before the release storeIsInitialized()outside locks (e.g.,IsInlineEnabled(),JITProcessMethod()) but safely delegate to methods that lock properly3. Inline Helper Methods in Header
Added
IsInitialized()andSetInitialized()to the header file as inline methods for:4. Optimize LoadAspects() Locking
Updated
LoadAspects()to:_cslock only for theswap()operation on_moduleAspectsModuleAspectsobjects outside the lock5. Remove Redundant Lock in GetAspectsModule()
Removed
CSGUARD(_cs)fromGetAspectsModule()since it delegates toGetModuleInfo(), which now properly locks. Avoids unnecessary nested locking (though safe due to recursiveCRITICAL_SECTIONon Windows).Reason for change
Fix critical race conditions causing flaky crashes in CI, particularly on Windows x86. The crashes manifested as STL internal errors during concurrent access to Dataflow's internal maps during JIT compilation and shutdown scenarios.
This error could also happen in customer installations, causing crashes.
Implementation details
Files changed:
tracer/src/Datadog.Tracer.Native/iast/dataflow.cpp- TOCTOU fixes, lock reordering, destructor synchronizationtracer/src/Datadog.Tracer.Native/iast/dataflow.h- Atomic flag declaration, inline helper methods with acquire/release semanticsKey synchronization pattern:
The fix leverages the recursive nature of Windows
CRITICAL_SECTION(used byCSGUARD) while eliminating TOCTOU races by ensuring all shared state access happens atomically with the initialization check under the same lock.Methods updated:
~Dataflow()- Lock before setting flag and destroying mapsGetAppDomain(),GetModuleInfo(),GetAspectsModule()- Check inside lockAppDomainShutdown(),ModuleUnloaded(),GetAspects()- Check inside lockIsInitialized()/SetInitialized()- Atomic with acquire/release memory orderingTest coverage
This fix addresses the root cause of the flaky Windows x86 CI failures. The existing CI pipeline validates the fix through:
Other details