[CI Visibility] Bound global coverage memory - #8926
Conversation
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8926) 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 (8926) - mean (73ms) : 70, 77
master - mean (72ms) : 69, 75
section Bailout
This PR (8926) - mean (78ms) : 74, 81
master - mean (79ms) : 75, 83
section CallTarget+Inlining+NGEN
This PR (8926) - mean (1,096ms) : 1035, 1156
master - mean (1,099ms) : 1029, 1168
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 (8926) - mean (115ms) : 108, 121
master - mean (115ms) : 109, 120
section Bailout
This PR (8926) - mean (112ms) : 108, 116
master - mean (113ms) : 108, 117
section CallTarget+Inlining+NGEN
This PR (8926) - mean (787ms) : 759, 815
master - mean (783ms) : 760, 807
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (101ms) : 95, 108
master - mean (98ms) : 94, 102
section Bailout
This PR (8926) - mean (101ms) : 96, 107
master - mean (99ms) : 97, 100
section CallTarget+Inlining+NGEN
This PR (8926) - mean (946ms) : 914, 978
master - mean (943ms) : 900, 987
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (96ms) : 94, 99
master - mean (100ms) : 94, 106
section Bailout
This PR (8926) - mean (102ms) : 96, 108
master - mean (99ms) : 95, 104
section CallTarget+Inlining+NGEN
This PR (8926) - mean (822ms) : 781, 862
master - mean (819ms) : 781, 857
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 (8926) - mean (209ms) : 205, 213
master - mean (206ms) : 202, 210
section Bailout
This PR (8926) - mean (214ms) : 211, 217
master - mean (209ms) : 204, 214
section CallTarget+Inlining+NGEN
This PR (8926) - mean (1,254ms) : 1216, 1292
master - mean (1,231ms) : 1172, 1289
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 (8926) - mean (300ms) : 295, 304
master - mean (293ms) : 287, 298
section Bailout
This PR (8926) - mean (301ms) : 297, 305
master - mean (293ms) : 289, 297
section CallTarget+Inlining+NGEN
This PR (8926) - mean (1,001ms) : 976, 1026
master - mean (981ms) : 954, 1008
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (294ms) : 288, 300
master - mean (288ms) : 283, 292
section Bailout
This PR (8926) - mean (294ms) : 289, 300
master - mean (288ms) : 284, 291
section CallTarget+Inlining+NGEN
This PR (8926) - mean (1,190ms) : 1157, 1222
master - mean (1,173ms) : 1143, 1203
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (294ms) : 288, 300
master - mean (286ms) : 282, 291
section Bailout
This PR (8926) - mean (294ms) : 290, 298
master - mean (286ms) : 281, 291
section CallTarget+Inlining+NGEN
This PR (8926) - mean (1,074ms) : 1008, 1141
master - mean (1,054ms) : 1006, 1102
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
dd-trace-dotnet/tracer/src/Datadog.Trace.Tools.Runner/CiUtils.cs
Lines 427 to 429 in 31856d7
When dotnet test uses Microsoft Testing Platform coverage, this branch deliberately omits the Datadog in-proc collector. However, RequestSeal() is only invoked from that collector's TestSessionEnd, while code coverage remains enabled and TestModule still publishes the new pending/raw global-coverage artifacts. Those artifacts therefore never receive ready markers; reusing an explicit coverage directory leaves an incomplete protocol set that makes subsequent reconciliation reject both the stale and newly produced coverage files. Add an equivalent end-of-run sealing path for the Testing Platform case, or avoid creating protocol artifacts there.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
BenchmarksBenchmark execution time: 2026-08-03 15:00:42 Comparing candidate commit 13d8b26 in PR branch Found 0 performance improvements and 2 performance regressions! Performance is the same for 69 metrics, 1 unstable metrics, 65 known flaky benchmarks, 61 flaky benchmarks without significant changes.
|
@chatgpt-codex-connector Addressed in a79fa2d. Global coverage is now finalized from TestOptimization shutdown after active modules are closed, so Microsoft Testing Platform runs seal their output even when the Datadog in-proc collector is intentionally omitted. The finalization path is idempotent and shared with the collector. I also added unit coverage plus an MTP end-to-end test that runs twice against the same coverage directory and verifies successful reconciliation. |
|
To use Codex here, create an environment for this repo. |
eee3854 to
c62a892
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c62a892b39
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
6cb87db to
bfd8734
Compare
Snapshots difference summaryThe following differences have been observed in committed snapshots. It is meant to help the reviewer. |
8a3be12 to
36bb32a
Compare
f74fb63 to
7f25e16
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f25e16a94
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 620fd7f719
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8a7c79749e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f1ec06ada3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary of changes
ModuleValuebuffers immediately.dotnet testcompletes.Reason for change
DefaultWithGlobalCoverageEventHandlerpreviously kept every completedCoverageContextContainerin_coveragesuntil global coverage was calculated at the end of the test process. Each context retained one or moreModuleValueinstances backed byMarshal.AllocHGlobal, so native memory grew with the number of completed tests rather than with the amount of unique code being measured.APMS-20099 reports this failure mode in a Windows VSTest/NUnit run with 5,134 tests: 60,863 live
ModuleValueinstances retained approximately 16 GB of native buffers and causedtesthost.exeto run out of memory beforeTestSessionEndcould perform the only cleanup.The fix must release completed contexts during the run without losing their contribution to the final union. It must also support multiple testhost processes, preserve the per-test payload, and avoid adding synchronization to the generated counter-increment hot path.
Implementation details
Release completed contexts without losing coverage
CoverageSessionHandlebinds each test to the exact handler, context, and lifecycle admission created at test start. This avoids closing the wrongAsyncLocalcontext and makes construction, abort, and teardown cleanup explicit.ModuleCoverageDatascans the existing byte or integer counter buffer once. A line is covered when its counter is non-zero; this preserves both line-execution and line-call-count modes, including counter overflow.GlobalCoverageAccumulator.finallyafter capture and merge, so its native buffers are released even if coverage processing fails.Preserve global coverage correctness
Moduleand retains the original metadata and executable bitmap for that module.Keep the probe hot path and IL contract unchanged
CoverageReporter<TMeta>.GetFileCounter(int)and receives the same native pointer used by the existing counter increment IL.AsyncLocalflow falls back to the process-global module buffer instead of reopening or writing to a disposed test context.Publish complete coverage across testhost processes
TestOptimizationshutdown hook seals the same idempotent finalization path, writes one immutable JSON artifact atomically, and removes the pending marker only after the artifact is durable.dotnet testinstrumentation combines only artifacts belonging to its run, applies the existing ITR backfill, and atomically publishes the finalsession-coverage-*.jsonfile.Test coverage
AsyncLocalflows, concurrent starts/snapshots/sealing, allocation and metadata failures, configured memory limits, atomic publication, run isolation, malformed artifacts, and ITR consumer behavior.GetFileCounterpointer shape, does not add exception handlers or invalidatetail.methods, and still releases buffers when instrumented code throws.testhostthrough the productiondd-trace ci runtool and packaged Datadog collector, using Coverlet 3.2.0 and 6.0.0.Other details