Make Runtime=NET task host handshake architecture-agnostic - #13890
Conversation
IsAllowedBitnessMismatch is the .NET task host child-side relaxation that lets a parent without an architecture bit on the wire (typically a .NET Framework MSBuild) connect to an SDK child that runs on x64. On Windows-ARM the SDK child runs as arm64 instead, but the function only considered expectedIsX64, so any arm64 child rejected the connection -> the launch times out and Runtime="NET" tasks fail with MSB4216. Also tolerate expectedIsArm64. True cross-arch mismatches (parent X64 vs child Arm64, or vice versa) remain rejected. Make the method internal static so the test project can exercise the tolerance matrix directly. The previous instance method did not touch any instance state. Partial fix for dotnet#13879 (Bug A). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes a child-side handshake check that prevented .NET Framework MSBuild parents from launching a Runtime="NET" task host on Windows-ARM. IsAllowedBitnessMismatch previously only tolerated an x64-expecting child when the parent sent no architecture bit; it now tolerates arm64-expecting children as well, while still rejecting true cross-arch mismatches (X64↔Arm64). The method is also promoted to internal static to make it directly unit-testable.
Changes:
- Extend
IsAllowedBitnessMismatchto acceptexpectedIsArm64in addition toexpectedIsX64. - Convert the method to
internal staticand refresh its doc comment. - Add unit tests covering the no-arch-bit-parent tolerance matrix (x64/arm64 child) and rejection of true cross-arch mismatches.
Show a summary per file
| File | Description |
|---|---|
| src/Shared/NodeEndpointOutOfProcBase.cs | Tolerate arm64-expecting child in bitness mismatch check; expose as internal static; update XML doc. |
| src/Build.UnitTests/BackEnd/NodeEndpointOutOfProcBase_Tests.cs | New #if NET tests for the tolerance matrix and cross-arch rejection. |
Copilot's findings
- Files reviewed: 2/2 changed files
- Comments generated: 0
There was a problem hiding this comment.
Review Summary — PR #13890
Well-scoped bug fix extending the .NET task host handshake tolerance to arm64 children. The logic change is correct and the approach is sound.
Findings
| # | Dimension | Severity | Summary |
|---|---|---|---|
| 1 | Test Coverage & Completeness | MODERATE | Missing test for "no-arch parent → no-arch child" (the path where receivedIsX86==true but method returns false) |
| 2 | Documentation Accuracy | NIT | Inherited mask comment has version/flags description inverted |
Clean Dimensions (22/24)
Backwards Compatibility ✓ · ChangeWave ✓ · Performance ✓ · Error Messages ✓ · Logging ✓ · String Comparison ✓ · API Surface ✓ · Target Authoring ✓ · Design ✓ · Cross-Platform ✓ · Code Simplification ✓ · Concurrency ✓ · Naming ✓ · SDK Integration ✓ · Idiomatic C# ✓ · File I/O ✓ · Build Infrastructure ✓ · Scope & PR Discipline ✓ · Evaluation Model ✓ · Correctness ✓ · Dependency Mgmt ✓ · Security ✓
Notes
- The
private → internal staticvisibility change is appropriate for testability; the class is alreadyinternaland the method is a pure stateless predicate. - The behavioral change is strictly a relaxation (accepts arm64 where previously only x64 was accepted), so no ChangeWave is needed.
- The fix correctly rejects true cross-arch mismatches (e.g., parent declares X64 but child expects Arm64).
Note
🔒 Integrity filter blocked 2 items
The following items were blocked because they don't meet the GitHub integrity level.
- #13890
pull_request_read: has lower integrity than agent requires. The agent cannot read data with integrity below "approved". - #13890
pull_request_read: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".
To allow these resources, lower min-integrity in your GitHub frontmatter:
tools:
github:
min-integrity: approved # merged | approved | unapproved | noneGenerated by Expert Code Review (on open) for issue #13890 · ● 5.5M
For NET task host launches the child process's architecture is determined by what the .NET SDK shipped (x64 today, arm64 in the future), not by the parent's process architecture. Emitting the parent's arch bit creates a wire-level mismatch with already-shipped SDK children whose arch differs (e.g. arm64 VS launching an x64 SDK MSBuild.dll, or amd64 VS launching an arm64 SDK MSBuild.dll). The existing child-side IsAllowedBitnessMismatch tolerance only accepts "parent sent no arch bit", so this currently fails with MSB4216. In CommunicationsUtilities.GetHandshakeOptions, suppress the X64/Arm64 bit when invoked by the parent for a NET task host (detected by Runtime="net" in the explicit TaskHostParameters). The child path (TaskHostParameters .Empty) is unaffected so already-deployed parents that still emit an arch bit continue to match. Combined with the child-side Arm64 tolerance in this PR, every parent/ child architecture combination now connects against every already-shipped SDK that has the original (x64-only) tolerance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add NoArchBitParent_NoArchBitChild_NotTolerated test (catches a regression that would simplify the return to just receivedIsX86). - Fix inverted comment on the 0x00FFFFFF mask (lower 24 bits are flags, upper byte is version). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@rainersigwald it would be great if you could also take a look :) Just want to be careful. |
…handshake comments - Remove the speculative 'arm64 in the future' note and condense the verbose NET task host arch-bit suppression comment to the underlying rule. - Rename parent/child to worker node/TaskHost node in comments, the isNetTaskHostWorkerNode variable, and the handshake unit tests. - Fix the stale inverted handshake mask comment at the IsAllowedBitnessMismatch call site. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@rainersigwald please approve if the changes look good to you |
|
@ViktorHofer mergeable? or do you plan to take action on last rainer's comment? |
…shake (dotnet/msbuild#13890) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* [release-notes] MSBuild in .NET 11 Preview 6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add bug-fix note for architecture-agnostic Runtime=NET task host handshake (dotnet/msbuild#13890) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Remove HTML comments from Preview 6 MSBuild release notes Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Chet Husk <chusk3@gmail.com>
* [release-notes] .NET 11 Preview 6 base metadata changes.json, features.json, build-metadata.json, and README for the .NET 11 Preview 6 milestone (VMR base v11.0.0-preview.5.26302.115 -> head release/11.0.1xx-preview6). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * [release-notes] C# in .NET 11 Preview 6 (#10460) * [release-notes] C# in .NET 11 Preview 6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update release-notes/11.0/preview/preview6/csharp.md --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Bill Wagner <wiwagn@microsoft.com> * [release-notes] MSBuild in .NET 11 Preview 6 (#10463) * [release-notes] MSBuild in .NET 11 Preview 6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add bug-fix note for architecture-agnostic Runtime=NET task host handshake (dotnet/msbuild#13890) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Remove HTML comments from Preview 6 MSBuild release notes Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Chet Husk <chusk3@gmail.com> * [release-notes] NuGet in .NET 11 Preview 6 (#10464) * [release-notes] NuGet in .NET 11 Preview 6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix STJ feature-flag env var value and remove VS reference Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Chet Husk <chusk3@gmail.com> * [release-notes] .NET SDK in .NET 11 Preview 6 (#10459) * [release-notes] .NET SDK in .NET 11 Preview 6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify NativeAOT CLI updates in preview6/sdk.md Updated the NativeAOT CLI section to clarify the unification of managed and NativeAOT parsers, and removed filtered content related to internal changes. * Add live running-tests display to dotnet test notes Document the in-flight test progress panel (dotnet/sdk#54486) and fix pre-existing trailing-space lint errors in the NativeAOT section. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Chet Husk <baronfel@users.noreply.github.com> Co-authored-by: Chet Husk <chusk3@gmail.com> * [release-notes] Windows Forms in .NET 11 Preview 6 (#10465) * [release-notes] Windows Forms in .NET 11 Preview 6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revise Windows Forms release notes for Preview 6 Updated release notes for .NET 11 Preview 6 to include bug fixes and improvements for various Windows Forms components. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Klaus Löffelmann <9663150+KlausLoeffelmann@users.noreply.github.com> * [release-notes] .NET MAUI in .NET 11 Preview 6 (#10467) * [release-notes] .NET MAUI in .NET 11 Preview 6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Draft .NET MAUI and friends notes for .NET 11 Preview 6 Combined highlights for .NET MAUI, .NET for Android, and .NET for iOS, Mac Catalyst, macOS, and tvOS: CollectionView2 on Windows, handler-based Shell on Android, Compatibility package removal, AOT-safe HybridWebView, Geolocation minimum-distance filter, a reliability wave, the AndroidMessageHandler HTTP-contract work, and the Apple platform toolchain and NSUrlSessionHandler updates. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Add Preview 6 items from MAUI maintainer review Incorporates jfversluis review feedback on #10467: - Android MediaPicker result recovery APIs (dotnet/maui#35455) - HybridWebView Android message-source filtering (dotnet/maui#35717) - XAML C# expression source generator CS1061 fix (dotnet/maui#35922) - Testable permissions via IPermissions/Permissions.Current (dotnet/maui#35987) - XA0149 warning for legacy __AndroidEnvironment__ resources (dotnet/android#11700) - Skip library proguard.txt with disallowed R8 global options (dotnet/android#11709) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: David Ortinau <david.ortinau@microsoft.com> * [release-notes] EF Core in .NET 11 Preview 6 (#10462) Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> * [release-notes] F# in .NET 11 Preview 6 (#10461) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * [release-notes] Containers in .NET 11 Preview 6 (#10468) * [release-notes] Containers in .NET 11 Preview 6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update release notes --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Logan Bussell <loganbussell@microsoft.com> * [release-notes] .NET Libraries in .NET 11 Preview 6 (#10457) * [release-notes] .NET Libraries in .NET 11 Preview 6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix async DataAnnotations sample after testing on the Preview 6 SDK AsyncValidationAttribute is overridden via the protected IsValidAsync (and IsValid) members, not GetValidationResultAsync (which is the public method the framework calls and is not virtual). Verified the corrected sample compiles and runs against the Preview 6 build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Verify Preview 6 library samples and fix inaccuracies - Stream adapters: read from the read-only stream via StreamContent/PostAsync instead of copying HttpContent into it - Cross-lane vectors: replace nonexistent Concat with ConcatLowerLower/LowerUpper/UpperLower/UpperUpper and drop preexisting Shuffle/ShuffleNative - Async validation: swap the unique-username example for a VAT registry lookup, layer StringLength and RegularExpression sync rules with the async rule, and add a server-side validation note Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Jeff Handley <jeffhandley@users.noreply.github.com> * [release-notes] ASP.NET Core in .NET 11 Preview 6 (#10456) * [release-notes] WPF in .NET 11 Preview 6 (#10466) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Throw InvalidOperationException for sync validation of async validator Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Apply late review suggestions from #10456 to the ASP.NET Core notes - OpenAPI unions: correct the third-party generator claim (ApiExplorer does not detect unions via JsonTypeInfoKind.Union; Swashbuckle/NSwag don't yet recognize unions). Per @DeagleGross review on #10456. - Blazor Virtualize: note that a user scroll during ScrollToIndexAsync wins. Per @ilonatommy review on #10456. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add P6 Blazor items to align with docs (dotnet/AspNetCore.Docs#37322) - CSRF: note that Blazor Web App templates no longer call app.UseAntiforgery(). - Bug fixes/Blazor: Virtualize is now CSP-compliant (#66680); session cookie is issued before streaming SSR for [SupplyParameterFromSession]/TempData (#66832). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Document 'Configure Blazor client behavior from the server' as a P6 feature WithBrowserOptions flows client-side Blazor.start configuration from the server in C# (log level, Server reconnection, SSR DOM preservation, WASM environment), serialized to the client across Server/WebAssembly/Auto render modes. Introduced in Preview 4 (server-to-browser config via DOM comment) and reshaped in Preview 6 (dotnet/aspnetcore#67337, proposal #66393). Includes the reshape/rename migration for earlier adopters. Sample build-verified on 11.0.100-preview.6.26359.118. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Correct Virtualize CSP note: data-blazor-virtualize-reserved-height Reviewing dotnet/AspNetCore.Docs#37322 surfaced that the attribute is data-blazor-virtualize-reserved-height (only the server-computed spacer height), not the generic data-blazor-style. Verified in the P6 source (Virtualize.cs / Virtualize.ts). @ilonatommy corrected the same wording on the docs PR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * [release-notes] .NET Runtime in .NET 11 Preview 6 (#10458) * [release-notes] .NET Runtime in .NET 11 Preview 6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Enrich Preview 6 runtime notes with additional verified features Fold verified .NET 11 Preview 6 runtime changes into runtime.md (JIT improvements, in-process crash logging, NativeAOT interface dispatch, SIMD lane APIs, and an expanded bug-fix list), and rebuild the TOC to match the current sections. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ade796bb-8052-4946-b204-a88518267e77 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Rich Lander <2608468+richlander@users.noreply.github.com> * fix markdown lint in preview6 containers note Co-authored-by: jongalloway <68539+jongalloway@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Bill Wagner <wiwagn@microsoft.com> Co-authored-by: Chet Husk <chusk3@gmail.com> Co-authored-by: Chet Husk <baronfel@users.noreply.github.com> Co-authored-by: Klaus Löffelmann <9663150+KlausLoeffelmann@users.noreply.github.com> Co-authored-by: David Ortinau <david.ortinau@microsoft.com> Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> Co-authored-by: Logan Bussell <loganbussell@microsoft.com> Co-authored-by: Jeff Handley <jeffhandley@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Rich Lander <2608468+richlander@users.noreply.github.com> Co-authored-by: Rahul Bhandari <rbhanda@microsoft.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jongalloway <68539+jongalloway@users.noreply.github.com>
Summary
Runtime="NET"task host launches fail withMSB4216whenever the worker node and TaskHost node architectures don't line up the way the original implementation expected. Tracked as #13879 (Bug A).Two coordinated handshake changes — one on each side — close every reasonable worker/TaskHost arch combination:
1. Worker node side —
CommunicationsUtilities.GetHandshakeOptionsFor a NET task host the launched TaskHost node's architecture is whatever the .NET SDK shipped, not the worker node's. Emitting the worker node's arch bit produces a wire-level mismatch with already-shipped SDK TaskHost nodes whose arch differs.
Suppress the
X64/Arm64bit when invoked by the worker node for a NET task host (detected byRuntime="net"in the explicitTaskHostParameters). The TaskHost-node path (TaskHostParameters.Empty) is unaffected, so already-deployed worker nodes that still emit an arch bit continue to match.2. TaskHost node side —
NodeEndpointOutOfProcBase.IsAllowedBitnessMismatchThe .NET task host side relaxation that lets a worker node without an arch bit on the wire connect to an SDK TaskHost node. Previously only tolerated
expected = X64, so any arm64 SDK TaskHost node rejected the connection. Now also toleratesexpected = Arm64. True cross-arch mismatches (workerX64↔ TaskHostArm64) remain rejected.Method is promoted to
internal staticso the test project can exercise the tolerance matrix directly. It was a stateless pure predicate already.Effect across worker node / SDK combinations
current= behavior with this PR applied (worker-node change in VS MSBuild, TaskHost-node change in a future SDK). For each combo, "current behavior" notes whether the SDK side needs to update.expectedIsX64tolerance)expectedIsArm64toleranceWhere each fix takes effect
expectedIsX64tolerance already covers the TaskHost node)The reported binlog (Roslyn build on Windows-ARM, SDK 10.0.108, x86 VS 18 MSBuild worker node) is the first row — needs the SDK side to pick this up.
Tests
src/Build.UnitTests/BackEnd/NodeEndpointOutOfProcBase_Tests.cs(6 cases):NoArchBitWorkerNode_X64TaskHost_IsToleratedNoArchBitWorkerNode_Arm64TaskHost_IsToleratedX64WorkerNode_X64TaskHost_NotConsideredMismatchX64WorkerNode_Arm64TaskHost_NotToleratedArm64WorkerNode_X64TaskHost_NotToleratedNoArchBitWorkerNode_NoArchBitTaskHost_NotTolerated(guards against a future simplification toreturn receivedIsX86;)src/Build.UnitTests/BackEnd/CommunicationsUtilities_Tests.cs(5 cases):GetHandshakeOptions_NetTaskHostWorkerNode_SuppressesArchBit× { x64, arm64, x86 }GetHandshakeOptions_NonNetTaskHostWorkerNode_KeepsX64ArchBitGetHandshakeOptions_NonNetTaskHostWorkerNode_KeepsArm64ArchBitGetHandshakeOptions_NetTaskHostNode_KeepsArchBitAll 11 pass on net10.0.
References