-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Fix unloadability issue #119196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix unloadability issue #119196
Conversation
…ced cleanup path for LoaderAllocators without any assemblies associated with them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request fixes a rare but critical crash in assembly unloading scenarios involving multiple Assembly Load Contexts (ALCs). The crash occurs when a DomainAssembly pointer remains in the AppDomain assembly list after the DomainAssembly was deleted, leading to access violations.
Key changes:
- Modified LoaderAllocator cleanup logic to defer deletion until all dependencies are properly notified
- Added
HasAttachedDynamicAssemblies()
method to better handle edge cases - Included comprehensive regression test that reproduces the original crash scenario
Reviewed Changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
src/coreclr/vm/loaderallocator.hpp |
Added HasAttachedDynamicAssemblies() method and fixed constructor initialization |
src/coreclr/vm/loaderallocator.cpp |
Updated cleanup logic to check for attached assemblies before forced cleanup, added debug logging |
src/tests/Regressions/coreclr/GitHub_116953/test116953.cs |
Main regression test reproducing the multi-ALC unloading scenario |
src/tests/Regressions/coreclr/GitHub_116953/test116953.csproj |
Test project configuration |
src/tests/Regressions/coreclr/GitHub_116953/AssemblyA.csproj |
Helper assembly A project |
src/tests/Regressions/coreclr/GitHub_116953/AssemblyB.csproj |
Helper assembly B project with dependencies |
src/tests/Regressions/coreclr/GitHub_116953/AssemblyC.csproj |
Helper assembly C project |
src/tests/Regressions/coreclr/GitHub_116953/ClassA.cs |
Simple test class for assembly A |
src/tests/Regressions/coreclr/GitHub_116953/ClassB.cs |
Test class with dependencies on A and C |
src/tests/Regressions/coreclr/GitHub_116953/ClassC.cs |
Simple test class for assembly C |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you!
backport to release/10.0 and release/9.0 ? |
/backport to release/10.0 |
Started backporting to release/10.0: https://github.com/dotnet/runtime/actions/runs/17560134946 |
There is a rare case when attempt to unload an assembly load context in multi-assembly load context scenario leads to access violation in the runtime.
The crash is caused by a DomainAssembly pointer in the AppDomain assembly list not being removed while the DomainAssembly was deleted. The fix is to defer deletion of the DomainAssembly until after all dependencies on the LoaderAllocator have notified the runtime that they are freed. Notably, the fix is to adjust a bit of logic where we were forcing the original LoaderAllocator to be cleaned up even if it wasn't found as free-able during the GCLoaderAllocator's logic. That needed to exist to handle the case of a LoaderAllocator without any associated DomainAssembly objects, but we can special case that specific scenario.
There is a detailed analysis in the #116953.
This change fixes it and adds a regression test that is a repro app provided in the issue converted to coreclr test.
Close #116953