Revert "Revert Load the tracer/profiler after guardrails checks"#6959
Conversation
Datadog Summary✅ Code Quality ✅ Code Security ✅ Dependencies ❌ Pipelines Next StepsThe following jobs failed due to platform errors: All Green / all-greenCheck Run Failed: installer_smoke_tests_arm64 due to some CI checks or statuses failing. Test Optimization ReportAll test runs ✅ 2 Total Test Services: 0 Failed, 2 Passed Test Services
Was this helpful? Give us feedback! |
There was a problem hiding this comment.
Pull Request Overview
This PR reverts earlier changes to the tracer/profiler initialization to address crashes in mixed-runtimes scenarios by ensuring each runtime has its own dispatcher instance. Key changes include reverting the LoadInstance method signature (removing extra parameters), updating logging messages to include error codes, and refactoring dispatcher initialization and unload logic.
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| shared/test/Datadog.Trace.ClrProfiler.Native.Tests/test_dynamic_instance.h | Reverted signature of LoadInstance |
| shared/src/native-src/dynamic_library_base.cpp | Updated logging message during Unload |
| shared/src/Datadog.Trace.ClrProfiler.Native/dynamic_instance.h & .cpp | Reverted LoadInstance signature changes |
| shared/src/Datadog.Trace.ClrProfiler.Native/dynamic_dispatcher.h & .cpp | Added Initialize method and updated error logging |
| shared/src/Datadog.Trace.ClrProfiler.Native/dllmain.cpp | Uses multiple dispatchers and updates DllCanUnloadNow |
| shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler_class_factory.cpp | Removed redundant LoadInstance call after QueryInterface |
| shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp | Adjusted initialization flow and combined log messages |
Datadog ReportAll test runs ✅ 2 Total Test Services: 0 Failed, 2 Passed Test Services
⌛ Performance Regressions vs Default Branch (2) |
BenchmarksBenchmarks Report for benchmark platform 🐌Benchmarks for #6959 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 ✔️ Fewer allocations 🎉
|
| Benchmark | Base Allocated | Diff Allocated | Change | Change % |
|---|---|---|---|---|
| Benchmarks.Trace.ActivityBenchmark.StartStopWithChild‑net472 | 6.16 KB | 6.08 KB | -76 B | -1.23% |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | StartStopWithChild |
net6.0 | 10.9μs | 59ns | 339ns | 0 | 0 | 0 | 5.54 KB |
| master | StartStopWithChild |
netcoreapp3.1 | 13.3μs | 70.8ns | 354ns | 0 | 0 | 0 | 5.74 KB |
| master | StartStopWithChild |
net472 | 21.4μs | 113ns | 679ns | 0.924 | 0.231 | 0 | 6.16 KB |
| #6959 | StartStopWithChild |
net6.0 | 10.1μs | 55.9ns | 331ns | 0 | 0 | 0 | 5.55 KB |
| #6959 | StartStopWithChild |
netcoreapp3.1 | 13.3μs | 71.5ns | 385ns | 0 | 0 | 0 | 5.75 KB |
| #6959 | StartStopWithChild |
net472 | 22.2μs | 122ns | 689ns | 1.06 | 0.318 | 0.106 | 6.08 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 | 955μs | 80.3ns | 300ns | 0 | 0 | 0 | 2.7 KB |
| master | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 1.02ms | 56.1ns | 210ns | 0 | 0 | 0 | 2.7 KB |
| master | WriteAndFlushEnrichedTraces |
net472 | 1.24ms | 4.73μs | 18.3μs | 0 | 0 | 0 | 3.31 KB |
| #6959 | WriteAndFlushEnrichedTraces |
net6.0 | 929μs | 87.3ns | 315ns | 0 | 0 | 0 | 2.72 KB |
| #6959 | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 1.03ms | 99.3ns | 344ns | 0 | 0 | 0 | 2.7 KB |
| #6959 | WriteAndFlushEnrichedTraces |
net472 | 1.24ms | 79.9ns | 309ns | 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 | 328μs | 1.13μs | 4.36μs | 0 | 0 | 0 | 197.06 KB |
| master | AllCycleSimpleBody |
netcoreapp3.1 | 478μs | 1.56μs | 6.05μs | 0 | 0 | 0 | 204.77 KB |
| master | AllCycleSimpleBody |
net472 | 435μs | 129ns | 499ns | 36.6 | 2.16 | 0 | 236.35 KB |
| master | AllCycleMoreComplexBody |
net6.0 | 336μs | 1.48μs | 5.53μs | 0 | 0 | 0 | 200.56 KB |
| master | AllCycleMoreComplexBody |
netcoreapp3.1 | 487μs | 458ns | 1.72μs | 0 | 0 | 0 | 208.18 KB |
| master | AllCycleMoreComplexBody |
net472 | 443μs | 128ns | 497ns | 36.6 | 2.16 | 0 | 239.87 KB |
| master | ObjectExtractorSimpleBody |
net6.0 | 319ns | 1.71ns | 7.65ns | 0 | 0 | 0 | 280 B |
| master | ObjectExtractorSimpleBody |
netcoreapp3.1 | 399ns | 2.1ns | 10.9ns | 0 | 0 | 0 | 272 B |
| master | ObjectExtractorSimpleBody |
net472 | 302ns | 0.029ns | 0.108ns | 0.0441 | 0 | 0 | 281 B |
| master | ObjectExtractorMoreComplexBody |
net6.0 | 6.25μs | 4.83ns | 17.4ns | 0 | 0 | 0 | 3.78 KB |
| master | ObjectExtractorMoreComplexBody |
netcoreapp3.1 | 7.97μs | 11ns | 42.8ns | 0 | 0 | 0 | 3.69 KB |
| master | ObjectExtractorMoreComplexBody |
net472 | 6.68μs | 6.59ns | 25.5ns | 0.602 | 0 | 0 | 3.8 KB |
| #6959 | AllCycleSimpleBody |
net6.0 | 332μs | 1.55μs | 6.02μs | 0 | 0 | 0 | 197.06 KB |
| #6959 | AllCycleSimpleBody |
netcoreapp3.1 | 506μs | 1.48μs | 5.74μs | 0 | 0 | 0 | 204.77 KB |
| #6959 | AllCycleSimpleBody |
net472 | 437μs | 111ns | 428ns | 36.6 | 2.16 | 0 | 236.35 KB |
| #6959 | AllCycleMoreComplexBody |
net6.0 | 338μs | 86.2ns | 334ns | 0 | 0 | 0 | 200.56 KB |
| #6959 | AllCycleMoreComplexBody |
netcoreapp3.1 | 494μs | 1.17μs | 4.54μs | 0 | 0 | 0 | 208.18 KB |
| #6959 | AllCycleMoreComplexBody |
net472 | 444μs | 462ns | 1.79μs | 36.6 | 2.16 | 0 | 239.87 KB |
| #6959 | ObjectExtractorSimpleBody |
net6.0 | 331ns | 1.67ns | 7.1ns | 0 | 0 | 0 | 280 B |
| #6959 | ObjectExtractorSimpleBody |
netcoreapp3.1 | 401ns | 1.97ns | 7.89ns | 0 | 0 | 0 | 272 B |
| #6959 | ObjectExtractorSimpleBody |
net472 | 301ns | 0.0249ns | 0.0899ns | 0.0444 | 0 | 0 | 281 B |
| #6959 | ObjectExtractorMoreComplexBody |
net6.0 | 6.26μs | 30.4ns | 125ns | 0 | 0 | 0 | 3.78 KB |
| #6959 | ObjectExtractorMoreComplexBody |
netcoreapp3.1 | 7.71μs | 31ns | 120ns | 0 | 0 | 0 | 3.69 KB |
| #6959 | ObjectExtractorMoreComplexBody |
net472 | 6.7μs | 6.39ns | 24.7ns | 0.603 | 0 | 0 | 3.8 KB |
Benchmarks.Trace.Asm.AppSecEncoderBenchmark - Unknown 🤷 Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | EncodeArgs |
net6.0 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| master | EncodeArgs |
netcoreapp3.1 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| master | EncodeArgs |
net472 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| master | EncodeLegacyArgs |
net6.0 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| master | EncodeLegacyArgs |
netcoreapp3.1 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| master | EncodeLegacyArgs |
net472 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | EncodeArgs |
net6.0 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | EncodeArgs |
netcoreapp3.1 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | EncodeArgs |
net472 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | EncodeLegacyArgs |
net6.0 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | EncodeLegacyArgs |
netcoreapp3.1 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | EncodeLegacyArgs |
net472 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
Benchmarks.Trace.Asm.AppSecWafBenchmark - Unknown 🤷 Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | RunWafRealisticBenchmark |
net6.0 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| master | RunWafRealisticBenchmark |
netcoreapp3.1 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| master | RunWafRealisticBenchmark |
net472 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| master | RunWafRealisticBenchmarkWithAttack |
net6.0 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| master | RunWafRealisticBenchmarkWithAttack |
netcoreapp3.1 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| master | RunWafRealisticBenchmarkWithAttack |
net472 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | RunWafRealisticBenchmark |
net6.0 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | RunWafRealisticBenchmark |
netcoreapp3.1 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | RunWafRealisticBenchmark |
net472 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | RunWafRealisticBenchmarkWithAttack |
net6.0 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | RunWafRealisticBenchmarkWithAttack |
netcoreapp3.1 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
| #6959 | RunWafRealisticBenchmarkWithAttack |
net472 | N/A | N/A | N/A | NaN | NaN | NaN | 0 b |
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.9μs | 31.5ns | 122ns | 0 | 0 | 0 | 14.53 KB |
| master | SendRequest |
netcoreapp3.1 | 71.4μs | 98.2ns | 368ns | 0 | 0 | 0 | 17.42 KB |
| master | SendRequest |
net472 | 0.0191ns | 0.00167ns | 0.00647ns | 0 | 0 | 0 | 0 b |
| #6959 | SendRequest |
net6.0 | 62.3μs | 100ns | 388ns | 0 | 0 | 0 | 14.53 KB |
| #6959 | SendRequest |
netcoreapp3.1 | 71.7μs | 67.6ns | 262ns | 0 | 0 | 0 | 17.42 KB |
| #6959 | SendRequest |
net472 | 0.015ns | 0.00221ns | 0.00855ns | 0 | 0 | 0 | 0 b |
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark - Same speed ✔️ More allocations ⚠️
More allocations ⚠️ in #6959
Benchmark
Base Allocated
Diff Allocated
Change
Change %
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net472
55.85 KB
56.36 KB
505 B
0.90%
| Benchmark | Base Allocated | Diff Allocated | Change | Change % |
|---|---|---|---|---|
| Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces‑net472 | 55.85 KB | 56.36 KB | 505 B | 0.90% |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | WriteAndFlushEnrichedTraces |
net6.0 | 695μs | 3.94μs | 26.7μs | 0 | 0 | 0 | 41.64 KB |
| master | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 742μs | 4.29μs | 34.4μs | 0 | 0 | 0 | 41.88 KB |
| master | WriteAndFlushEnrichedTraces |
net472 | 972μs | 3.16μs | 12.2μs | 4.46 | 0 | 0 | 55.85 KB |
| #6959 | WriteAndFlushEnrichedTraces |
net6.0 | 725μs | 4.05μs | 26.2μs | 0 | 0 | 0 | 41.62 KB |
| #6959 | WriteAndFlushEnrichedTraces |
netcoreapp3.1 | 687μs | 3.63μs | 19.2μs | 0 | 0 | 0 | 41.89 KB |
| #6959 | WriteAndFlushEnrichedTraces |
net472 | 899μs | 1.58μs | 6.12μs | 8.33 | 0 | 0 | 56.36 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.98μs | 9.05ns | 36.2ns | 0 | 0 | 0 | 1.03 KB |
| master | ExecuteNonQuery |
netcoreapp3.1 | 2.46μs | 2.28ns | 8.83ns | 0 | 0 | 0 | 1.02 KB |
| master | ExecuteNonQuery |
net472 | 2.8μs | 5.37ns | 20.8ns | 0.153 | 0.014 | 0 | 995 B |
| #6959 | ExecuteNonQuery |
net6.0 | 2.01μs | 5.39ns | 20.9ns | 0 | 0 | 0 | 1.03 KB |
| #6959 | ExecuteNonQuery |
netcoreapp3.1 | 2.42μs | 9.34ns | 35ns | 0 | 0 | 0 | 1.02 KB |
| #6959 | ExecuteNonQuery |
net472 | 2.9μs | 1.98ns | 7.68ns | 0.146 | 0.0146 | 0 | 995 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.75μs | 7.98ns | 31.9ns | 0 | 0 | 0 | 1.04 KB |
| master | CallElasticsearch |
netcoreapp3.1 | 2.33μs | 9.99ns | 38.7ns | 0 | 0 | 0 | 1.04 KB |
| master | CallElasticsearch |
net472 | 3.46μs | 2.47ns | 9.57ns | 0.155 | 0 | 0 | 1.05 KB |
| master | CallElasticsearchAsync |
net6.0 | 1.85μs | 1.36ns | 4.89ns | 0 | 0 | 0 | 1.02 KB |
| master | CallElasticsearchAsync |
netcoreapp3.1 | 2.33μs | 10.7ns | 41.5ns | 0 | 0 | 0 | 1.09 KB |
| master | CallElasticsearchAsync |
net472 | 3.77μs | 4.59ns | 17.8ns | 0.169 | 0 | 0 | 1.11 KB |
| #6959 | CallElasticsearch |
net6.0 | 1.82μs | 5.28ns | 20.5ns | 0 | 0 | 0 | 1.04 KB |
| #6959 | CallElasticsearch |
netcoreapp3.1 | 2.28μs | 9.53ns | 36.9ns | 0 | 0 | 0 | 1.04 KB |
| #6959 | CallElasticsearch |
net472 | 3.48μs | 3.22ns | 12.5ns | 0.157 | 0 | 0 | 1.05 KB |
| #6959 | CallElasticsearchAsync |
net6.0 | 1.8μs | 8.48ns | 35ns | 0 | 0 | 0 | 1.02 KB |
| #6959 | CallElasticsearchAsync |
netcoreapp3.1 | 2.36μs | 6.18ns | 23.1ns | 0 | 0 | 0 | 1.09 KB |
| #6959 | CallElasticsearchAsync |
net472 | 3.76μs | 3.44ns | 13.3ns | 0.169 | 0 | 0 | 1.11 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.85μs | 9.2ns | 39ns | 0 | 0 | 0 | 960 B |
| master | ExecuteAsync |
netcoreapp3.1 | 2.3μs | 9.74ns | 37.7ns | 0 | 0 | 0 | 960 B |
| master | ExecuteAsync |
net472 | 2.75μs | 1.98ns | 7.13ns | 0.136 | 0 | 0 | 923 B |
| #6959 | ExecuteAsync |
net6.0 | 1.82μs | 2.87ns | 11.1ns | 0 | 0 | 0 | 960 B |
| #6959 | ExecuteAsync |
netcoreapp3.1 | 2.34μs | 6.29ns | 24.4ns | 0 | 0 | 0 | 960 B |
| #6959 | ExecuteAsync |
net472 | 2.53μs | 3.75ns | 14.5ns | 0.138 | 0 | 0 | 923 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 | 6.91μs | 21.3ns | 79.7ns | 0 | 0 | 0 | 2.37 KB |
| master | SendAsync |
netcoreapp3.1 | 8.78μs | 21ns | 81.5ns | 0 | 0 | 0 | 2.9 KB |
| master | SendAsync |
net472 | 12.2μs | 5.25ns | 20.3ns | 0.484 | 0 | 0 | 3.19 KB |
| #6959 | SendAsync |
net6.0 | 6.85μs | 14.5ns | 56ns | 0 | 0 | 0 | 2.37 KB |
| #6959 | SendAsync |
netcoreapp3.1 | 8.46μs | 4.35ns | 16.3ns | 0 | 0 | 0 | 2.9 KB |
| #6959 | SendAsync |
net472 | 12.3μs | 9.12ns | 35.3ns | 0.488 | 0 | 0 | 3.19 KB |
Benchmarks.Trace.Iast.StringAspectsBenchmark - Faster 🎉 More allocations ⚠️
Faster 🎉 in #6959
Benchmark
base/diff
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0
3.006
1,385,600.00
460,950.00
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑netcoreapp3.1
1.157
538,350.00
465,100.00
multimodal
More allocations ⚠️ in #6959
Benchmark
Base Allocated
Diff Allocated
Change
Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net472
278.53 KB
286.72 KB
8.19 KB
2.94%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑net6.0
43.78 KB
44.18 KB
400 B
0.91%
Fewer allocations 🎉 in #6959
Benchmark
Base Allocated
Diff Allocated
Change
Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑netcoreapp3.1
277.58 KB
274.77 KB
-2.81 KB
-1.01%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0
342.2 KB
257.98 KB
-84.22 KB
-24.61%
| Benchmark | base/diff | Base Median (ns) | Diff Median (ns) | Modality |
|---|---|---|---|---|
| Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0 | 3.006 | 1,385,600.00 | 460,950.00 | |
| Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑netcoreapp3.1 | 1.157 | 538,350.00 | 465,100.00 | multimodal |
| Benchmark | Base Allocated | Diff Allocated | Change | Change % |
|---|---|---|---|---|
| Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net472 | 278.53 KB | 286.72 KB | 8.19 KB | 2.94% |
| Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑net6.0 | 43.78 KB | 44.18 KB | 400 B | 0.91% |
| Benchmark | Base Allocated | Diff Allocated | Change | Change % |
|---|---|---|---|---|
| Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑netcoreapp3.1 | 277.58 KB | 274.77 KB | -2.81 KB | -1.01% |
| Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0 | 342.2 KB | 257.98 KB | -84.22 KB | -24.61% |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | StringConcatBenchmark |
net6.0 | 45.1μs | 343ns | 3.22μs | 0 | 0 | 0 | 43.78 KB |
| master | StringConcatBenchmark |
netcoreapp3.1 | 48.2μs | 275ns | 1.82μs | 0 | 0 | 0 | 42.73 KB |
| master | StringConcatBenchmark |
net472 | 57.1μs | 200ns | 749ns | 0 | 0 | 0 | 57.34 KB |
| master | StringConcatAspectBenchmark |
net6.0 | 1.39ms | 2.27μs | 7.87μs | 0 | 0 | 0 | 342.2 KB |
| master | StringConcatAspectBenchmark |
netcoreapp3.1 | 538μs | 1.96μs | 7.33μs | 0 | 0 | 0 | 277.58 KB |
| master | StringConcatAspectBenchmark |
net472 | 412μs | 2.31μs | 15.1μs | 0 | 0 | 0 | 278.53 KB |
| #6959 | StringConcatBenchmark |
net6.0 | 44.3μs | 255ns | 1.92μs | 0 | 0 | 0 | 44.18 KB |
| #6959 | StringConcatBenchmark |
netcoreapp3.1 | 51.9μs | 349ns | 3.34μs | 0 | 0 | 0 | 42.81 KB |
| #6959 | StringConcatBenchmark |
net472 | 57.5μs | 121ns | 435ns | 0 | 0 | 0 | 57.34 KB |
| #6959 | StringConcatAspectBenchmark |
net6.0 | 462μs | 1.7μs | 6.81μs | 0 | 0 | 0 | 257.98 KB |
| #6959 | StringConcatAspectBenchmark |
netcoreapp3.1 | 469μs | 5.97μs | 59.1μs | 0 | 0 | 0 | 274.77 KB |
| #6959 | StringConcatAspectBenchmark |
net472 | 406μs | 2.19μs | 11.4μs | 0 | 0 | 0 | 286.72 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.61μs | 4ns | 15ns | 0 | 0 | 0 | 1.76 KB |
| master | EnrichedLog |
netcoreapp3.1 | 3.47μs | 11.7ns | 45.3ns | 0 | 0 | 0 | 1.76 KB |
| master | EnrichedLog |
net472 | 3.93μs | 2.14ns | 7.7ns | 0.255 | 0 | 0 | 1.69 KB |
| #6959 | EnrichedLog |
net6.0 | 2.57μs | 12.6ns | 48.9ns | 0 | 0 | 0 | 1.76 KB |
| #6959 | EnrichedLog |
netcoreapp3.1 | 3.46μs | 17.4ns | 79.6ns | 0 | 0 | 0 | 1.76 KB |
| #6959 | EnrichedLog |
net472 | 3.82μs | 1.82ns | 6.8ns | 0.267 | 0 | 0 | 1.69 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 | 122μs | 44.1ns | 159ns | 0 | 0 | 0 | 4.37 KB |
| master | EnrichedLog |
netcoreapp3.1 | 127μs | 443ns | 1.6μs | 0 | 0 | 0 | 4.37 KB |
| master | EnrichedLog |
net472 | 167μs | 96.1ns | 360ns | 0 | 0 | 0 | 4.57 KB |
| #6959 | EnrichedLog |
net6.0 | 123μs | 124ns | 464ns | 0 | 0 | 0 | 4.37 KB |
| #6959 | EnrichedLog |
netcoreapp3.1 | 130μs | 437ns | 1.69μs | 0 | 0 | 0 | 4.37 KB |
| #6959 | EnrichedLog |
net472 | 167μs | 202ns | 781ns | 0 | 0 | 0 | 4.57 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.07μs | 20.6ns | 80ns | 0 | 0 | 0 | 2.32 KB |
| master | EnrichedLog |
netcoreapp3.1 | 6.84μs | 5.2ns | 19.4ns | 0 | 0 | 0 | 2.32 KB |
| master | EnrichedLog |
net472 | 7.29μs | 3.56ns | 13.3ns | 0.326 | 0 | 0 | 2.14 KB |
| #6959 | EnrichedLog |
net6.0 | 5.01μs | 16ns | 59.9ns | 0 | 0 | 0 | 2.32 KB |
| #6959 | EnrichedLog |
netcoreapp3.1 | 6.56μs | 15.3ns | 59.1ns | 0 | 0 | 0 | 2.32 KB |
| #6959 | EnrichedLog |
net472 | 7.34μs | 8.82ns | 34.1ns | 0.326 | 0 | 0 | 2.14 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 | 2.06μs | 2.43ns | 9.11ns | 0 | 0 | 0 | 1.21 KB |
| master | SendReceive |
netcoreapp3.1 | 2.55μs | 11.9ns | 47.6ns | 0 | 0 | 0 | 1.21 KB |
| master | SendReceive |
net472 | 3.05μs | 2.5ns | 9.69ns | 0.183 | 0 | 0 | 1.21 KB |
| #6959 | SendReceive |
net6.0 | 2.03μs | 10.7ns | 57.6ns | 0 | 0 | 0 | 1.21 KB |
| #6959 | SendReceive |
netcoreapp3.1 | 2.56μs | 12.5ns | 50.1ns | 0 | 0 | 0 | 1.21 KB |
| #6959 | SendReceive |
net472 | 3.01μs | 6.59ns | 25.5ns | 0.179 | 0 | 0 | 1.21 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.47μs | 3.87ns | 14.5ns | 0 | 0 | 0 | 1.64 KB |
| master | EnrichedLog |
netcoreapp3.1 | 5.76μs | 19.1ns | 74.1ns | 0 | 0 | 0 | 1.69 KB |
| master | EnrichedLog |
net472 | 6.87μs | 8.56ns | 33.2ns | 0.312 | 0 | 0 | 2.08 KB |
| #6959 | EnrichedLog |
net6.0 | 4.26μs | 7.18ns | 27.8ns | 0 | 0 | 0 | 1.64 KB |
| #6959 | EnrichedLog |
netcoreapp3.1 | 5.69μs | 18.3ns | 70.8ns | 0 | 0 | 0 | 1.69 KB |
| #6959 | EnrichedLog |
net472 | 6.74μs | 3.21ns | 12.4ns | 0.3 | 0 | 0 | 2.08 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 | 745ns | 3.85ns | 14.9ns | 0 | 0 | 0 | 584 B |
| master | StartFinishSpan |
netcoreapp3.1 | 946ns | 4.5ns | 17.4ns | 0 | 0 | 0 | 584 B |
| master | StartFinishSpan |
net472 | 919ns | 0.235ns | 0.88ns | 0.0919 | 0 | 0 | 586 B |
| master | StartFinishScope |
net6.0 | 923ns | 0.334ns | 1.29ns | 0 | 0 | 0 | 704 B |
| master | StartFinishScope |
netcoreapp3.1 | 1.16μs | 5.44ns | 21.8ns | 0 | 0 | 0 | 704 B |
| master | StartFinishScope |
net472 | 1.12μs | 0.0531ns | 0.184ns | 0.101 | 0 | 0 | 666 B |
| #6959 | StartFinishSpan |
net6.0 | 744ns | 3.47ns | 13ns | 0 | 0 | 0 | 584 B |
| #6959 | StartFinishSpan |
netcoreapp3.1 | 921ns | 4ns | 15ns | 0 | 0 | 0 | 584 B |
| #6959 | StartFinishSpan |
net472 | 903ns | 0.229ns | 0.886ns | 0.0906 | 0 | 0 | 586 B |
| #6959 | StartFinishScope |
net6.0 | 917ns | 5.02ns | 27.5ns | 0 | 0 | 0 | 704 B |
| #6959 | StartFinishScope |
netcoreapp3.1 | 1.16μs | 6.16ns | 32ns | 0 | 0 | 0 | 704 B |
| #6959 | StartFinishScope |
net472 | 1.17μs | 2.43ns | 9.41ns | 0.1 | 0 | 0 | 666 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.03μs | 0.448ns | 1.74ns | 0 | 0 | 0 | 704 B |
| master | RunOnMethodBegin |
netcoreapp3.1 | 1.37μs | 2.42ns | 8.73ns | 0 | 0 | 0 | 704 B |
| master | RunOnMethodBegin |
net472 | 1.38μs | 1.11ns | 4.3ns | 0.104 | 0 | 0 | 666 B |
| #6959 | RunOnMethodBegin |
net6.0 | 1.07μs | 4.43ns | 18.8ns | 0 | 0 | 0 | 704 B |
| #6959 | RunOnMethodBegin |
netcoreapp3.1 | 1.37μs | 4.84ns | 18.7ns | 0 | 0 | 0 | 704 B |
| #6959 | RunOnMethodBegin |
net472 | 1.38μs | 1.09ns | 4.24ns | 0.104 | 0 | 0 | 666 B |
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing the following branches/commits: Execution-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 shown 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). gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6959) - mean (68ms) : 66, 70
. : milestone, 68,
master - mean (68ms) : 66, 69
. : milestone, 68,
section CallTarget+Inlining+NGEN
This PR (6959) - mean (1,007ms) : 985, 1030
. : milestone, 1007,
master - mean (1,004ms) : 982, 1027
. : milestone, 1004,
gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6959) - mean (102ms) : 100, 104
. : milestone, 102,
master - mean (102ms) : 100, 104
. : milestone, 102,
section CallTarget+Inlining+NGEN
This PR (6959) - mean (692ms) : 671, 714
. : milestone, 692,
master - mean (694ms) : 678, 710
. : milestone, 694,
gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6959) - mean (89ms) : 86, 91
. : milestone, 89,
master - mean (89ms) : 86, 91
. : milestone, 89,
section CallTarget+Inlining+NGEN
This PR (6959) - mean (653ms) : 628, 678
. : milestone, 653,
master - mean (653ms) : 629, 678
. : milestone, 653,
gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.8)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6959) - mean (189ms) : 185, 194
. : milestone, 189,
master - mean (189ms) : 185, 193
. : milestone, 189,
section CallTarget+Inlining+NGEN
This PR (6959) - mean (1,108ms) : 1085, 1131
. : milestone, 1108,
master - mean (1,114ms) : 1086, 1142
. : milestone, 1114,
gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6959) - mean (268ms) : 264, 273
. : milestone, 268,
master - mean (269ms) : 265, 272
. : milestone, 269,
section CallTarget+Inlining+NGEN
This PR (6959) - mean (880ms) : 846, 913
. : milestone, 880,
master - mean (884ms) : 851, 917
. : milestone, 884,
gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6959) - mean (262ms) : 258, 266
. : milestone, 262,
master - mean (261ms) : 257, 265
. : milestone, 261,
section CallTarget+Inlining+NGEN
This PR (6959) - mean (867ms) : 832, 902
. : milestone, 867,
master - mean (869ms) : 836, 902
. : milestone, 869,
|
andrewlock
left a comment
There was a problem hiding this comment.
LGTM, but what do I know? 🙈
|
|
||
| IDynamicDispatcher* dispatcher; | ||
| // Keep track of all dispatchers to broadcast DllCanUnloadNow | ||
| // Note: we don't actually do anything meaningful in DllCanUnloadNow so maybe we could remove it |
There was a problem hiding this comment.
Could we do anything meaningful? 🤔 Is there a relevant TODO we should be thinking about?
There was a problem hiding this comment.
No clue, I honestly don't even know why it's there.
| // The continuous profiler isn't currently supported on ARM | ||
| SkipOn.PlatformAndArchitecture(SkipOn.PlatformValue.Linux, SkipOn.ArchitectureValue.ARM64); |
There was a problem hiding this comment.
This worked before, because we would load the continuous profiler into memory, even though it wasn't supported, correct?
There was a problem hiding this comment.
Correct, so the diagnostic tool would mistakenly think that the profiler was working (even though it was just loaded)
daniel-romano-DD
left a comment
There was a problem hiding this comment.
Looks good. Thanks a lot (and fingers crossed)
zacharycmontoya
left a comment
There was a problem hiding this comment.
A little late to the party but LGTM
) This reverts commit c66626c.
…cks" (#6959)' (#6986) ## Summary of changes This reverts commit c66626c. ## Reason for change We're seeing crashes in arm64 on fedora 35 only, when we initialize the WAF. Reverting this for now while we investigate to unblock `master` ## Implementation details Revert the reapplied revert ## Test coverage Covered by existing ## Other details
## Summary of changes - Revert "Revert 'Reapply "Revert Load the tracer/profiler after guardrails checks" (#6959)' (#6986)" #7051 - Avoid calling `dlclose` on glibc 2.34-2.36 ## Reason for change We want to make sure we only load the tracer/profiler libraries _after_ we have run guardrails checks. However, repeated attempts to do this were causing crashes in our smoke tests on Fedora 35, on arm64 only. After an (extensive) investigation, we finally tracked this down to a bug in glibc itself. The full explanation is given below, but the upshot is that calling `dlclose` on this buggy glibc version can cause crashes at some later point. ## Implementation details - Includes the "original" implementation that moves the tracer/profiler after guardrails checks - Before calling `dlclose`, check to see if we're on a buggy version of glibc - This is complicated by the fact we run the _same_ binary on glibc and musl, so we have to make the glibc call _dynamically_, instead of linking directly against the `gnu_get_libc_version` method. - We avoid trying to load libc if we detect that we're on Alpine by checking for `/etc/alpine-release`. This is slightly annoying, but required in the native loader code. - If we _do_ manage to call the glibc version, we check against the blocklist. If the version is on it, we avoid ever calling dlclose. ## Test coverage We have run repeated tests against the previously crashing tests, and this has resolved the issue. Nevertheless, our recommendation for customers should definitely be to upgrade to a stable version of glibc wherever possible ## Other details Overview of the bug: In certain versions of glibc, there is a TLS-reuse bug that can cause crashes when unloading shared libraries. The bug was introduced in 2.34, fixed in 2.36 on x86-64, and fixed in 2.37 on aarch64. See [the bug here](https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=3921c5b40f293c57cb326f58713c924b0662ef59) or [the explanation of the bug on Fedora](https://bugzilla.redhat.com/show_bug.cgi?id=2251557) (which is where we saw the crashing issue). glibc 2.34 shipped with a regression: after a `dlclose()` of a library that carried dynamic-TLS, the loader could reuse the same "module-ID" for a different library _without_ first clearing the associated DTV (Dynamic Thread Vector) entry. The next time any code accessed that TLS slot it could read or write an unmapped address, which cases a `SIGSEGV`. This manifested as a crash in the WAF when we called `ddwaf_context_info` on arm64. It explicitly happens on arm64 when we unload the continuous profiler shortly after loading it (which is normal because it's not supported). It manifests in this scenario because `ddwaf_context_init` starts like this: ```assembly +128 bl __tls_get_addr ; ask glibc for the TLS slot for libddwaf +136 mrs x11, TPIDR_EL0 ; TLS base for this thread +140 ldrb w9, [x11, x0] ; <–– boom if x0 points to a stale DTV entry ``` When we unload the continuous profiler and call `dlcose`, it causes the glibc loader to hand out a recycled module-ID to `libddwaf`. When `ddwaf_context_init` tries to access TLS in the `ldrb` instruction, `x11 + x0` is outside every mapped version, and so it crashes. Note that although calling `dlclose` with the continuous profiler _may_ trigger the issue (the actual crash is flaky depending on load/unload timing and address layout), unloading _any_ library that is is built with `__thread`/`thread_local` data could trigger the crash. To minimize the risk of hitting this issue, we avoid calling `dlclose` entirely on the flaky glibc versions For more details [see doc](https://docs.google.com/document/d/1aptwmprnd83VTZMKxrrTqmBF6eOayjCL36kj9LujCE8/edit?tab=t.0#heading=h.nytiofltvdb5) Affected distros: | Distribution | Version / Release | glibc Version | | ----------------- | ----------------------------- | ------------- | | Fedora | 35 | 2.34 | | Fedora | 37 | 2.36 | | Ubuntu | 21.10 ("Impish Indri") | 2.34 | | Ubuntu | 22.04 LTS ("Jammy Jellyfish") | 2.35 | | Debian | 12 ("Bookworm") | 2.36 | | RHEL | 9 | 2.34 | | CentOS | 9 | 2.34 | | Amazon Linux 2023 | default | 2.34 |
## Summary of changes - Revert "Revert 'Reapply "Revert Load the tracer/profiler after guardrails checks" (#6959)' (#6986)" #7051 - Avoid calling `dlclose` on glibc 2.34-2.36 ## Reason for change We want to make sure we only load the tracer/profiler libraries _after_ we have run guardrails checks. However, repeated attempts to do this were causing crashes in our smoke tests on Fedora 35, on arm64 only. After an (extensive) investigation, we finally tracked this down to a bug in glibc itself. The full explanation is given below, but the upshot is that calling `dlclose` on this buggy glibc version can cause crashes at some later point. ## Implementation details - Includes the "original" implementation that moves the tracer/profiler after guardrails checks - Before calling `dlclose`, check to see if we're on a buggy version of glibc - This is complicated by the fact we run the _same_ binary on glibc and musl, so we have to make the glibc call _dynamically_, instead of linking directly against the `gnu_get_libc_version` method. - We avoid trying to load libc if we detect that we're on Alpine by checking for `/etc/alpine-release`. This is slightly annoying, but required in the native loader code. - If we _do_ manage to call the glibc version, we check against the blocklist. If the version is on it, we avoid ever calling dlclose. ## Test coverage We have run repeated tests against the previously crashing tests, and this has resolved the issue. Nevertheless, our recommendation for customers should definitely be to upgrade to a stable version of glibc wherever possible ## Other details Overview of the bug: In certain versions of glibc, there is a TLS-reuse bug that can cause crashes when unloading shared libraries. The bug was introduced in 2.34, fixed in 2.36 on x86-64, and fixed in 2.37 on aarch64. See [the bug here](https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=3921c5b40f293c57cb326f58713c924b0662ef59) or [the explanation of the bug on Fedora](https://bugzilla.redhat.com/show_bug.cgi?id=2251557) (which is where we saw the crashing issue). glibc 2.34 shipped with a regression: after a `dlclose()` of a library that carried dynamic-TLS, the loader could reuse the same "module-ID" for a different library _without_ first clearing the associated DTV (Dynamic Thread Vector) entry. The next time any code accessed that TLS slot it could read or write an unmapped address, which cases a `SIGSEGV`. This manifested as a crash in the WAF when we called `ddwaf_context_info` on arm64. It explicitly happens on arm64 when we unload the continuous profiler shortly after loading it (which is normal because it's not supported). It manifests in this scenario because `ddwaf_context_init` starts like this: ```assembly +128 bl __tls_get_addr ; ask glibc for the TLS slot for libddwaf +136 mrs x11, TPIDR_EL0 ; TLS base for this thread +140 ldrb w9, [x11, x0] ; <–– boom if x0 points to a stale DTV entry ``` When we unload the continuous profiler and call `dlcose`, it causes the glibc loader to hand out a recycled module-ID to `libddwaf`. When `ddwaf_context_init` tries to access TLS in the `ldrb` instruction, `x11 + x0` is outside every mapped version, and so it crashes. Note that although calling `dlclose` with the continuous profiler _may_ trigger the issue (the actual crash is flaky depending on load/unload timing and address layout), unloading _any_ library that is is built with `__thread`/`thread_local` data could trigger the crash. To minimize the risk of hitting this issue, we avoid calling `dlclose` entirely on the flaky glibc versions For more details [see doc](https://docs.google.com/document/d/1aptwmprnd83VTZMKxrrTqmBF6eOayjCL36kj9LujCE8/edit?tab=t.0#heading=h.nytiofltvdb5) Affected distros: | Distribution | Version / Release | glibc Version | | ----------------- | ----------------------------- | ------------- | | Fedora | 35 | 2.34 | | Fedora | 37 | 2.36 | | Ubuntu | 21.10 ("Impish Indri") | 2.34 | | Ubuntu | 22.04 LTS ("Jammy Jellyfish") | 2.35 | | Debian | 12 ("Bookworm") | 2.36 | | RHEL | 9 | 2.34 | | CentOS | 9 | 2.34 | | Amazon Linux 2023 | default | 2.34 |
Reverts #6200 It was crashing in mixed-runtimes scenario because we added a safeguard against double-initialization in the dispatcher, which incidentally caused the tracer to be initialized twice (which, it turns out, it doesn't like). Fixed by making sure each runtime gets its own instance of the dispatcher.
…cks" (#6959)' (#6986) ## Summary of changes This reverts commit c66626c. ## Reason for change We're seeing crashes in arm64 on fedora 35 only, when we initialize the WAF. Reverting this for now while we investigate to unblock `master` ## Implementation details Revert the reapplied revert ## Test coverage Covered by existing ## Other details
## Summary of changes - Revert "Revert 'Reapply "Revert Load the tracer/profiler after guardrails checks" (#6959)' (#6986)" #7051 - Avoid calling `dlclose` on glibc 2.34-2.36 ## Reason for change We want to make sure we only load the tracer/profiler libraries _after_ we have run guardrails checks. However, repeated attempts to do this were causing crashes in our smoke tests on Fedora 35, on arm64 only. After an (extensive) investigation, we finally tracked this down to a bug in glibc itself. The full explanation is given below, but the upshot is that calling `dlclose` on this buggy glibc version can cause crashes at some later point. ## Implementation details - Includes the "original" implementation that moves the tracer/profiler after guardrails checks - Before calling `dlclose`, check to see if we're on a buggy version of glibc - This is complicated by the fact we run the _same_ binary on glibc and musl, so we have to make the glibc call _dynamically_, instead of linking directly against the `gnu_get_libc_version` method. - We avoid trying to load libc if we detect that we're on Alpine by checking for `/etc/alpine-release`. This is slightly annoying, but required in the native loader code. - If we _do_ manage to call the glibc version, we check against the blocklist. If the version is on it, we avoid ever calling dlclose. ## Test coverage We have run repeated tests against the previously crashing tests, and this has resolved the issue. Nevertheless, our recommendation for customers should definitely be to upgrade to a stable version of glibc wherever possible ## Other details Overview of the bug: In certain versions of glibc, there is a TLS-reuse bug that can cause crashes when unloading shared libraries. The bug was introduced in 2.34, fixed in 2.36 on x86-64, and fixed in 2.37 on aarch64. See [the bug here](https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=3921c5b40f293c57cb326f58713c924b0662ef59) or [the explanation of the bug on Fedora](https://bugzilla.redhat.com/show_bug.cgi?id=2251557) (which is where we saw the crashing issue). glibc 2.34 shipped with a regression: after a `dlclose()` of a library that carried dynamic-TLS, the loader could reuse the same "module-ID" for a different library _without_ first clearing the associated DTV (Dynamic Thread Vector) entry. The next time any code accessed that TLS slot it could read or write an unmapped address, which cases a `SIGSEGV`. This manifested as a crash in the WAF when we called `ddwaf_context_info` on arm64. It explicitly happens on arm64 when we unload the continuous profiler shortly after loading it (which is normal because it's not supported). It manifests in this scenario because `ddwaf_context_init` starts like this: ```assembly +128 bl __tls_get_addr ; ask glibc for the TLS slot for libddwaf +136 mrs x11, TPIDR_EL0 ; TLS base for this thread +140 ldrb w9, [x11, x0] ; <–– boom if x0 points to a stale DTV entry ``` When we unload the continuous profiler and call `dlcose`, it causes the glibc loader to hand out a recycled module-ID to `libddwaf`. When `ddwaf_context_init` tries to access TLS in the `ldrb` instruction, `x11 + x0` is outside every mapped version, and so it crashes. Note that although calling `dlclose` with the continuous profiler _may_ trigger the issue (the actual crash is flaky depending on load/unload timing and address layout), unloading _any_ library that is is built with `__thread`/`thread_local` data could trigger the crash. To minimize the risk of hitting this issue, we avoid calling `dlclose` entirely on the flaky glibc versions For more details [see doc](https://docs.google.com/document/d/1aptwmprnd83VTZMKxrrTqmBF6eOayjCL36kj9LujCE8/edit?tab=t.0#heading=h.nytiofltvdb5) Affected distros: | Distribution | Version / Release | glibc Version | | ----------------- | ----------------------------- | ------------- | | Fedora | 35 | 2.34 | | Fedora | 37 | 2.36 | | Ubuntu | 21.10 ("Impish Indri") | 2.34 | | Ubuntu | 22.04 LTS ("Jammy Jellyfish") | 2.35 | | Debian | 12 ("Bookworm") | 2.36 | | RHEL | 9 | 2.34 | | CentOS | 9 | 2.34 | | Amazon Linux 2023 | default | 2.34 |
Reverts #6200
It was crashing in mixed-runtimes scenario because we added a safeguard against double-initialization in the dispatcher, which incidentally caused the tracer to be initialized twice (which, it turns out, it doesn't like). Fixed by making sure each runtime gets its own instance of the dispatcher.