Uh oh!
There was an error while loading. Please reload this page.
Freeze .NET 11 data contracts - #131858
Conversation
In preparation for RC, all data contract versions are now considered frozen. Going forward: - Any changes to the contract version definitions need to be compatible with diagnostic tools that use the definitions as they exist now. - The supported contract versions in the data descriptor should not change for the remainder of .NET 11. - Supported contract versions may change in future development branches, but the breaking changes this will create for diagnostic tools should be carefully considered and managed. The data descriptor header version is bumped to 2 and cDAC now rejects any prior data descriptor. This ensures that cDAC does not attempt to parse any .NET 11 development or preview build where we were not enforcing the contract versioning rules. This change also does some initial doc and test updates but it is likely we need both stronger test enforcement of the versioning rules and more explicit guidance about what runtime changes are or aren't compatible.
|
Azure Pipelines: Successfully started running 5 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
noahfalk
commented
Aug 5, 2026
I'm marking this 'no-merge' until our last data contract changes land. |
There was a problem hiding this comment.
Pull request overview
This PR bumps the cDAC physical data descriptor version to 2 and enforces strict rejection of any contract descriptor whose version is not 2, aligning implementation, test infrastructure, and documentation around a “frozen” contract set for .NET 11.
Changes:
- Enforce a single supported physical data descriptor version (
2) inContractDescriptorTargetand add unit tests for unsupported versions (including sub-descriptors). - Update descriptor producers/stubs to emit version
2(build tool model + native stub descriptor). - Refresh data contract documentation and cDAC contributor guidance to reflect the versioning/freeze rules.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/native/managed/cdac/tests/UnitTests/ContractDescriptor/TargetTests.SubDescriptors.cs | Adds regression coverage for rejecting unsupported versions in nested/sub-descriptors. |
| src/native/managed/cdac/tests/UnitTests/ContractDescriptor/TargetTests.cs | Adds regression coverage for rejecting missing/unsupported descriptor versions. |
| src/native/managed/cdac/tests/TestInfrastructure/ContractDescriptor/ContractDescriptorBuilder.cs | Updates test descriptor builder default version to 2 and adds a SetVersion hook for negative tests. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs | Enforces version == 2 at descriptor ingestion time (main + sub-descriptors). |
| src/coreclr/vm/datadescriptor/datadescriptor.inc | Adds a release-branch guidance comment about frozen contract versions for .NET 11. |
| src/coreclr/tools/cdac-build-tool/DataDescriptorModel.cs | Updates generated physical descriptor version from 1 to 2. |
| src/coreclr/debug/datadescriptor-shared/contractdescriptorstub.c | Updates stub descriptor JSON to version 2. |
| docs/design/datacontracts/datacontracts_design.md | Clarifies contract versioning semantics and “frozen from RC” expectations. |
| docs/design/datacontracts/data_descriptor.md | Updates spec text to version 2 and tightens rejection guidance. |
| docs/design/datacontracts/contract-descriptor.md | Updates the example descriptor version to 2. |
| .github/instructions/cdac.instructions.md | Adjusts repo guidance wording around dump compatibility and removes branch-conditional framing. |
Suppressed comments (1)
docs/design/datacontracts/data_descriptor.md:143
- The spec lists the optional top-level key as
"sub-descriptors", but the implementation and test infrastructure serialize/parse this assubDescriptors(camelCase). Keeping the docs aligned avoids tool authors looking for the wrong JSON property name.
* `"version": 2`
* optional `"baseline": "BASELINE_ID"` see below
* `"types": TYPES_DESCRIPTOR` see below
* `"globals": GLOBALS_DESCRIPTOR` see below
* optional `"sub-descriptors": SUB_DESCRIPTORS_DESCRIPTOR` see below
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (4)
docs/design/datacontracts/data_descriptor.md:143
- The JSON key for sub-descriptors is documented as "sub-descriptors" here, but the serializer/parser use camelCase ("subDescriptors"). Using the hyphenated key would be ignored by the current ContractDescriptorParser (UnmappedMemberHandling.Skip), so the doc should match the actual key name.
* `"version": 2`
* optional `"baseline": "BASELINE_ID"` see below
* `"types": TYPES_DESCRIPTOR` see below
* `"globals": GLOBALS_DESCRIPTOR` see below
* optional `"sub-descriptors": SUB_DESCRIPTORS_DESCRIPTOR` see below
docs/design/datacontracts/data_descriptor.md:129
- The doc says tooling must reject physical descriptors whose version is not 2, but the repo still contains a baseline descriptor at version 0 (docs/design/datacontracts/data/empty.jsonc). Either that baseline file needs to be updated to version 2 (and any other shipped baselines verified), or this statement needs to be qualified so it matches the supported inputs.
This is version 2 of the physical descriptor. Diagnostic tooling must reject physical descriptors
whose version is not 2.
docs/design/datacontracts/data_descriptor.md:350
- This example section still uses the hyphenated JSON key "sub-descriptors" later in the block (after the version/baseline entries), but the runtime/build-tool JSON uses "subDescriptors" (camelCase) and ContractDescriptorParser binds to that name. Tools following the example as-written would fail to discover sub-descriptors.
{
"version": 2,
"baseline": "example-64",
docs/design/datacontracts/contract-descriptor.md:79
- The example further down uses the JSON key "sub-descriptors" and the name "GCDescriptor", but the current JSON serialization/parsing expects "subDescriptors" and CoreCLR uses the sub-descriptor name "GC" (see CDAC_GLOBAL_SUB_DESCRIPTOR(GC, ...) in src/coreclr/vm/datadescriptor/datadescriptor.inc). The example should match the actual key/name so diagnostic tools implement the right shape.
{
"version": 2,
"baseline": "example-64",
"types":
{
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
jkoritzinsky
commented
Aug 5, 2026
Do we want to add the contract baseline files for .NET 11 as per the initial cdac design? |
I didn't have a plan to do it at least. I do recall initial discussion of it during .NET 10 and then during .NET 11 I hadn't heard further mention of it. I got the impression it had been abandoned or de-prioritized during the time that I was away from the project. Despite having initially suggested it myself early in .NET 10 once we started digging into it more deeply I changed my stance and felt the size savings didn't justify the complexity. If I am unaware of some past decisions I definitely want to know, but unless someone believes the baselining is very important my preference would be to move ahead without it for now. I checked our current descriptor sizes and we are at ~20KB for coreclr and 5-7KB for NativeAOT so that gives a ballpark figure of what is at stake for binary/minidump size metrics. |
|
Azure Pipelines: Successfully started running 5 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
am11
commented
Aug 9, 2026
Is this tied to the .NET version with a new release every time? If it is, we could just use the major version number instead of parallel counting. That way, we don't have to manually map which descriptor version belongs to which product version. |
hoyosjs
commented
Aug 10, 2026
/ba-g .ext failures are on initializetion path - this is in other PRs and needs investigation in diagnostics. |
hoyosjs
commented
Aug 10, 2026
They are not necessarily bumped in parallel. A lot of contracts are likely to remain stable and others will likely rev forward. This is about the header version for the data descriptor itself - mostly to signify breaking changes in the descriptor format. In this case - mark it as the snapshot where we expect things to start working. We can ignore anything from before. I don't necessarily see us reving this often. |
Uh oh!
There was an error while loading. Please reload this page.
In preparation for RC, all data contract versions are now considered frozen. Going forward: - Any changes to the contract version definitions need to be compatible with diagnostic tools that use the definitions as they exist now. - The supported contract versions in the data descriptor should not change for the remainder of .NET 11. - Supported contract versions may change in future development branches, but the breaking changes this will create for diagnostic tools should be carefully considered and managed. The data descriptor header version is bumped to 2 and cDAC now rejects any prior data descriptor. This ensures that cDAC does not attempt to parse any .NET 11 development or preview build where we were not enforcing the contract versioning rules. This change also does some initial doc and test updates but it is likely we need both stronger test enforcement of the versioning rules and more explicit guidance about what runtime changes are or aren't compatible. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
## Summary Update the ILC-generated NativeAOT managed type sub-descriptor to emit data descriptor version 2. .NET 11 data contracts were frozen in #131858, which updated the reader to reject descriptors older than version 2. The separate NativeAOT managed descriptor writer was missed and continued emitting version 0. As a result, the matching DataContractReader packages reject NativeAOT binaries produced from the same build, preventing cDAC initialization. ## Testing Internal cDAC dump and end-to-end tests exposed this issue across Windows and Linux architectures with: `Unsupported data descriptor version '0'. Expected version 2.` This change aligns the NativeAOT sub-descriptor with the frozen descriptor format. Copilot-Session: 95c4aedd-f09e-42d7-8c9f-f439297576a6
In preparation for RC, all data contract versions are now considered frozen. Going forward:
The data descriptor header version is bumped to 2 and cDAC now rejects any prior data descriptor. This ensures that cDAC does not attempt to parse any .NET 11 development or preview build where we were not enforcing the contract versioning rules.
This change also does some initial doc and test updates but it is likely we need both stronger test enforcement of the versioning rules and more explicit guidance about what runtime changes are or aren't compatible.
@dotnet/dotnet-diag @jkotas@davidwrighton