Skip to content

[Hot Reload] Add assembly modification safety net. Fixes #26072 - #26417

Open
rolfbjarne wants to merge 2 commits into
mainfrom
dev/rolf/hot-reload-safety-net
Open

[Hot Reload] Add assembly modification safety net. Fixes #26072#26417
rolfbjarne wants to merge 2 commits into
mainfrom
dev/rolf/hot-reload-safety-net

Conversation

@rolfbjarne

Copy link
Copy Markdown
Member

[Hot Reload] Add assembly modification safety net. Fixes #26072

Add the HotReloadCompatibleBuild MSBuild default and enforce that reloadable user assemblies are not modified during compatible builds.

The safety net reports a normal linker error when a Copy assembly would be saved. NativeAOT builds default HotReloadCompatibleBuild to false, and the build-property documentation now describes the behavior.

Fixes #26072

🤖 Pull request created by Copilot

rolfbjarne and others added 2 commits August 6, 2026 16:31
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 6, 2026 14:33
@rolfbjarne
rolfbjarne requested a review from dalexsoto as a code owner August 6, 2026 14:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Hot Reload compatibility “safety net” to prevent reloadable (Copy) assemblies from being re-saved during HotReloadCompatibleBuild builds, and updates build defaults/documentation so NativeAOT builds don’t opt into this mode by default.

Changes:

  • Add a guard in AppBundleRewriter.SaveAssembly that reports an error and skips saving when HotReloadCompatibleBuild is enabled for a reloadable (Copy) assembly.
  • Default $(HotReloadCompatibleBuild) to Debug for non-NativeAOT builds, and to false for NativeAOT.
  • Update build-property documentation to reflect the NativeAOT default behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
tools/dotnet-linker/AppBundleRewriter.cs Adds the enforcement check that blocks saving reloadable assemblies during Hot Reload compatible builds.
dotnet/targets/Xamarin.Shared.Sdk.targets Adjusts MSBuild defaults so NativeAOT doesn’t enable HotReloadCompatibleBuild by default.
docs/building-apps/build-properties.md Documents the updated default (non-NativeAOT Debug => true; otherwise false).
Suppressed comments (2)

tools/dotnet-linker/AppBundleRewriter.cs:1507

  • 🤖 💡 Error message — The error text says the assembly “was modified”, but this guard is actually about preventing any reloadable assembly from being saved/re-serialized (which can happen even for metadata-preservation reasons). Consider wording that explains the byte-for-byte constraint and points to $(HotReloadCompatibleBuild) as the controlling switch.
				configuration.Logger.LogError (ErrorHelper.CreateError (99, $"The assembly '{assembly.Name.Name}' is reloadable, but was modified during a Hot Reload compatible build."));

tools/dotnet-linker/AppBundleRewriter.cs:1509

  • 🤖 💡 Testing — This new safety-net behavior (failing when a reloadable/Copy assembly would be saved under HotReloadCompatibleBuild) doesn’t appear to have a regression test. Given there’s already a dedicated assembly-preparer test harness (tests/assembly-preparer/BaseClass.cs), it would be good to add a focused test that exercises this specific failure mode and asserts on the emitted error (and code, once it’s dedicated).
			if (configuration.HotReloadCompatibleBuild && action == AssemblyAction.Copy && assembly != PlatformAssembly) {
				configuration.Logger.LogError (ErrorHelper.CreateError (99, $"The assembly '{assembly.Name.Name}' is reloadable, but was modified during a Hot Reload compatible build."));
				return;
			}

Comment thread tools/dotnet-linker/AppBundleRewriter.cs
@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

✅ API diff for current PR / commit

NET (empty diffs)

✅ API diff vs stable

NET (empty diffs)

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: b9e7df2a3f6eff2bccb84a0fbd37c480762e86fc [PR build]

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

🔥 [PR Build #b9e7df2] Build failed (Build macOS tests) 🔥

Build failed for the job 'Build macOS tests' (with job status 'Failed')

Pipeline on Agent
Hash: b9e7df2a3f6eff2bccb84a0fbd37c480762e86fc [PR build]

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

🔥 [CI Build #b9e7df2] Test results 🔥

Test results

❌ Tests failed on VSTS: test results

5 tests crashed, 36 tests failed, 144 tests passed.

Failures

❌ dotnettests tests (iOS)

1 tests failed, 0 tests passed.

Failed tests

  • DotNet tests: Failed (Execution failed with exit code 1)
    • Xamarin.Tests.AppIconTest.AlternateAppIcon(iOS,"ios-arm64"): 'dotnet build' failed with exit code 1
      Full command: /Users/cloudtest/vss/_work/1/s/macios/builds/downloads/dotnet-sdk-10.0.400-...
    • Xamarin.Tests.AppIconTest.AlternateAppIcons(iOS,"ios-arm64"): 'dotnet build' failed with exit code 1
      Full command: /Users/cloudtest/vss/_work/1/s/macios/builds/downloads/dotnet-sdk-10.0.400-...
    • Xamarin.Tests.AppIconTest.AppIcon_1(iOS,"ios-arm64"): 'dotnet build' failed with exit code 1
      Full command: /Users/cloudtest/vss/_work/1/s/macios/builds/downloads/dotnet-sdk-10.0.400-...
    • ... and 33 more

Html Report (VSDrops) Download

❌ dotnettests tests (MacCatalyst)

1 tests failed, 0 tests passed.

Failed tests

  • DotNet tests: Failed (Execution failed with exit code 1)
    • Xamarin.Tests.DotNetProjectTest.BuildFatMonoTouchTest(MacCatalys...: 'dotnet build' failed with exit code 1
      Full command: /Users/cloudtest/vss/_work/1/s/macios/builds/downloads/dotnet-sdk-10.0.400-...
    • Xamarin.Tests.DotNetProjectTest.BuildInterdependentBindingProjec...: 'dotnet build' failed with exit code 1
      Full command: /Users/cloudtest/vss/_work/1/s/macios/builds/downloads/dotnet-sdk-10.0.400-...
    • Xamarin.Tests.TrimmerWarningsTest.TrimmerWarningsManagedStaticRe...: 'dotnet build' failed with exit code 1
      Full command: /Users/cloudtest/vss/_work/1/s/macios/builds/downloads/dotnet-sdk-10.0.400-...

Html Report (VSDrops) Download

❌ dotnettests tests (macOS)

1 tests failed, 0 tests passed.

Failed tests

  • DotNet tests: Failed (Execution failed with exit code 1)
    • Xamarin.Tests.TrimmerWarningsTest.TrimmerWarningsManagedStaticRe...: 'dotnet build' failed with exit code 1
      Full command: /Users/cloudtest/vss/_work/1/s/macios/builds/downloads/dotnet-sdk-10.0.400-...

Html Report (VSDrops) Download

❌ dotnettests tests (tvOS)

1 tests failed, 0 tests passed.

Failed tests

  • DotNet tests: Failed (Execution failed with exit code 1)
    • Xamarin.Tests.AppIconTest.AlternateAppIcon(TVOS,"tvos-arm64"): 'dotnet build' failed with exit code 1
      Full command: /Users/cloudtest/vss/_work/1/s/macios/builds/downloads/dotnet-sdk-10.0.400-...
    • Xamarin.Tests.AppIconTest.AlternateAppIcons(TVOS,"tvos-arm64"): 'dotnet build' failed with exit code 1
      Full command: /Users/cloudtest/vss/_work/1/s/macios/builds/downloads/dotnet-sdk-10.0.400-...
    • Xamarin.Tests.AppIconTest.AppIcon_1(TVOS,"tvos-arm64"): 'dotnet build' failed with exit code 1
      Full command: /Users/cloudtest/vss/_work/1/s/macios/builds/downloads/dotnet-sdk-10.0.400-...
    • ... and 15 more

Html Report (VSDrops) Download

❌ interdependent-binding-projects tests

3 tests failed, 1 tests passed.

Failed tests

  • interdependent-binding-projects/Mac Catalyst/Debug: BuildFailure
  • interdependent-binding-projects/iOS - simulator/Debug: BuildFailure
  • interdependent-binding-projects/tvOS - simulator/Debug: BuildFailure ( (failed to parse the logs: The Writer is closed or in error state.))

Html Report (VSDrops) Download

❌ linker tests (iOS)

2 tests failed, 13 tests passed.

Failed tests

  • link sdk/iOS - simulator/Debug: BuildFailure
  • dont link/iOS - simulator/Debug (PrepareAssemblies, MonoVM, Managed Static Registrar): BuildFailure ( (failed to parse the logs: The Writer is closed or in error state.))

Html Report (VSDrops) Download

❌ linker tests (MacCatalyst)

2 tests failed, 13 tests passed.

Failed tests

  • dont link/Mac Catalyst/Debug (PrepareAssemblies, MonoVM, Managed Static Registrar): BuildFailure
  • link sdk/Mac Catalyst/Debug: BuildFailure

Html Report (VSDrops) Download

❌ linker tests (macOS)

4 tests failed, 17 tests passed.

Failed tests

  • dont link/macOS/Debug (PrepareAssemblies, CoreCLR, Managed Static Registrar): BuildFailure
  • dont link/macOS/Debug (PrepareAssemblies, CoreCLR, Trimmable Static Registrar): BuildFailure
  • link sdk/macOS/Debug: BuildFailure
  • link sdk/macOS/Debug (PrepareAssemblies, CoreCLR, Trimmable Static Registrar): BuildFailure

Html Report (VSDrops) Download

❌ linker tests (tvOS)

2 tests failed, 13 tests passed.

Failed tests

  • link sdk/tvOS - simulator/Debug: BuildFailure
  • dont link/tvOS - simulator/Debug (PrepareAssemblies, MonoVM, Managed Static Registrar): BuildFailure

Html Report (VSDrops) Download

❌ monotouch tests (iOS)

5 tests failed, 14 tests passed.

Failed tests

  • monotouch-test/iOS - simulator/Debug: BuildFailure
  • monotouch-test/iOS - simulator/Debug (LinkSdk): BuildFailure ( (failed to parse the logs: The Writer is closed or in error state.))
  • monotouch-test/iOS - simulator/Debug (static registrar): BuildFailure
  • monotouch-test/iOS - simulator/Debug (managed static registrar): BuildFailure
  • monotouch-test/iOS - simulator/Debug (interpreter): BuildFailure

Html Report (VSDrops) Download

❌ monotouch tests (MacCatalyst)

4 tests failed, 14 tests passed.

Failed tests

  • monotouch-test/Mac Catalyst/Debug: BuildFailure
  • monotouch-test/Mac Catalyst/Debug (managed static registrar): BuildFailure ( (failed to parse the logs: The Writer is closed or in error state.))
  • monotouch-test/Mac Catalyst/Debug (static registrar): BuildFailure ( (failed to parse the logs: The Writer is closed or in error state.))
  • monotouch-test/Mac Catalyst/Debug (interpreter): BuildFailure ( (failed to parse the logs: The Writer is closed or in error state.))

Html Report (VSDrops) Download

❌ monotouch tests (macOS)

4 tests failed, 17 tests passed.

Failed tests

  • monotouch-test/macOS/Debug (PrepareAssemblies, Trimmable Static Registrar, link sdk): BuildFailure
  • monotouch-test/macOS/Debug (managed static registrar): BuildFailure
  • monotouch-test/macOS/Debug (trimmable static registrar): BuildFailure
  • monotouch-test/macOS/Release (trimmable static registrar): BuildFailure ( (failed to parse the logs: The Writer is closed or in error state.))

Html Report (VSDrops) Download

❌ monotouch tests (tvOS)

5 tests failed, 14 tests passed.

Failed tests

  • monotouch-test/tvOS - simulator/Debug: BuildFailure
  • monotouch-test/tvOS - simulator/Debug (LinkSdk): BuildFailure
  • monotouch-test/tvOS - simulator/Debug (static registrar): BuildFailure
  • monotouch-test/tvOS - simulator/Debug (managed static registrar): BuildFailure
  • monotouch-test/tvOS - simulator/Debug (interpreter): BuildFailure

Html Report (VSDrops) Download

❌ windows tests

1 tests failed, 2 tests passed.

Failed tests

  • Remote .NET tests/Xamarin.Tests.WindowsTest.RemoteTest(iOS,"ios-arm64"): Failed: 'dotnet build' failed with exit code 1

  • Remote .NET tests/Xamarin.Tests.WindowsTest.AssemblyPreparerRemoteTest(iOS,"ios-arm64"): Failed: 'dotnet build' failed with exit code 1

  • Remote .NET tests/Xamarin.Tests.WindowsTest.BundleStructureWithRemoteMac(iOS,"ios-arm64",All,"Debug"): Failed: 'dotnet build' failed with exit code 1

  • Remote .NET tests/Xamarin.Tests.WindowsTest.PluralRuntimeIdentifiersWithRemoteMac(iOS,"ios-arm64","Debug"): Failed: 'dotnet build' timed out after 00:10:00

  • Remote .NET tests/Xamarin.Tests.DotNetProjectTest.BuildProjectsWithExtensionsOnRemoteWindows(iOS,"ios-arm64",False): Failed: 'dotnet build' failed with exit code 1

Html Report (VSDrops) Download

❌ Tests on macOS Monterey (12) tests

⚠️ Tests did not run because the Build macOS tests job failed.

Html Report (VSDrops) Download

❌ Tests on macOS Ventura (13) tests

⚠️ Tests did not run because the Build macOS tests job failed.

Html Report (VSDrops) Download

❌ Tests on macOS Sonoma (14) tests

⚠️ Tests did not run because the Build macOS tests job failed.

Html Report (VSDrops) Download

❌ Tests on macOS Sequoia (15) tests

⚠️ Tests did not run because the Build macOS tests job failed.

Html Report (VSDrops) Download

❌ Tests on macOS Tahoe (26) tests

⚠️ Tests did not run because the Build macOS tests job failed.

Html Report (VSDrops) Download

Successes

✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download
✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (Multiple platforms): All 1 tests passed. Html Report (VSDrops) Download
✅ framework: All 2 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 4 tests passed. Html Report (VSDrops) Download
✅ generator: All 5 tests passed. Html Report (VSDrops) Download
✅ introspection: All 4 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
✅ sharpie: All 1 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. Html Report (VSDrops) Download

macOS tests

Linux Build Verification

Linux build succeeded

Pipeline on Agent
Hash: b9e7df2a3f6eff2bccb84a0fbd37c480762e86fc [PR build]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Hot Reload] Add $(HotReloadCompatibleBuild) MSBuild property + assembly-preparer safety net

3 participants