-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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 #48579 #49387
Fix #48579 #49387
Conversation
|
||
using (assemblyLoadContext.EnterContextualReflection()) | ||
{ | ||
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(dynamicAssemblyName, assemblyBuilderAccess); | ||
assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(dynamicAssemblyName, assemblyBuilderAccess); |
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.
I don't understand the change... what is this fixing?
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.
The AssemblyBuilder
was in the local scope of the using
statement. If a dynamic assembly is created with the AssemblyBuilderAccess.RunAndCollect
parameter, this could lead to the fact that at the time of checking the Assert
condition it was already removed from memory. I think changing the scope of the AsemblyBuilder
instance will solve the problem of floating test failure.
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.
assemblyBuilder
is never used; in a release build, these should produce exactly the same IL. Even if this fixes it for a debug build, where this could extend the lifetime of the instance until after the using block and prevent it from being collected before then, is this test never run in a release build?
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.
Yes, the IL code was the same. Rewrote the test so that the AssemblyBuilder instance is used in the Assert test. The local load test did not issue any errors for an hour.
Please revert the change in #50592 as part of this PR. |
@kunalspathak Who else can review this PR? |
@stephentoub has already reviewed and asked question. Could you please answer and suggest a better fix? |
@kunalspathak @stephentoub The question was answered, but no feedback was received. |
@Ap0k - Sorry for the delay. I have started various CI stress pipelines which will verify if your fix works. |
@kunalspathak Okay. Waiting for test results. |
Looks like the test still fails for same reason, so it might not be the right fix. https://dev.azure.com/dnceng/public/_build/results?buildId=1132503&view=ms.vss-test-web.build-test-results-tab&runId=34375692&resultId=109547&paneView=dotnet-dnceng.dnceng-build-release-tasks.helix-test-information-tab |
@kunalspathak Can you provide instructions for running a stress test locally? Maybe in my last launch I did not take into account any parameters. |
Sure, you need to set the following environment variable. The failure is on Windows x64.
Let me know if you need anything else. |
Is it necessary to somehow change the configuration in testmix_gc.config? |
No, that should not be needed. |
Local test results:
|
I have kicked off another GCStress run.
I do not fully understand this fix and might need to check with @stephentoub on what he thinks.
Why is the test changed? Was earlier the test was not validating the appropriate behaviour? |
In the previous version of the test, a dynamic assembly with the same name was created for different ALCs. This could lead to incorrect test behavior. For example, first of all, create an assembly in ALC.Default, a search took place and the test completed successfully. Then a dynamic assembly was created for the unloaded ALC, but a search by name led to the fact that the assembly was taken from ALC.Default (this is due to the peculiarities of ALC.Assemblies) and the test failed. |
@kunalspathak what are the test results? I see from the logs that the test we are interested in has passed :) |
There are lot of other failures that were not there before your changes. I have kicked off another CI job for main to double check if they are related to your changes or not. Could you also check some of the failures and see if they are related to your change? |
@kunalspathak Ok, I'll check |
From the latest main CI runs, it looks like all those test also fail on main, so might not be related to your change. @stephentoub - do you mind reviewing the PR once again? |
@kunalspathak Who else can review this PR? |
@agocke @vitek-karas @VSadov - Can someone review this PR? |
@@ -147,7 +147,7 @@ private static IntPtr ResolveUnmanagedDllUsingEvent(string unmanagedDllName, Ass | |||
|
|||
AssemblyLoadContext? loadContextForAssembly = null; | |||
|
|||
RuntimeAssembly? rtAsm = assembly as RuntimeAssembly; | |||
RuntimeAssembly? rtAsm = GetRuntimeAssembly(assembly); |
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.
This is a great fix - thanks a lot for finding this.
That said I would prefer if we made this a separate PR from the test fix. In that PR we should also add tests for this fix. My understanding is that it fixes two observable things:
- The fact that
GetLoadContext
returns null for dynamic assemblies - The fact that dynamic assemblies don't show up in
AssemblyLoadContext.Assemblies
(even though they do show up inAppDomain.GetAssemblies
)
Both of these should have tests (which are apparently missing).
After that PR is in, then we can fix the test which is the purpose of this PR.
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.
Ok, I'll put this fix in a separate PR with the appropriate tests.
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.
The same bug exists in ValidateAssemblyNameWithSimpleName
. I filed a new issue for it: #53181
But it might be a good idea to fix both at the same time.
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.
No problem) I'll do it
} | ||
|
||
Assert.IsTrue(assemblyLoadContext.Assemblies.Any(a => AssemblyName.ReferenceMatchesDefinition(a.GetName(), dynamicAssemblyName))); | ||
Assert.IsTrue(assemblyLoadContext == AssemblyLoadContext.GetLoadContext(assemblyBuilder)); |
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.
With the fix in CoreLib I would expect both approaches to work - the comparison of ALC as well as searching for the assembly in ALC.Assemblies. Is that true?
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.
Yes, provided that the name of the dynamic assembly is unique for each context (default and unloaded).
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.
Returned the search for dynamic assembly in ALC.Assemblies. The dynamic assembly name is unique for each ALC.
|
||
using (assemblyLoadContext.EnterContextualReflection()) | ||
{ | ||
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(dynamicAssemblyName, assemblyBuilderAccess); | ||
assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(dynamicAssemblyName, assemblyBuilderAccess); | ||
} | ||
|
||
Assert.IsTrue(assemblyLoadContext.Assemblies.Any(a => AssemblyName.ReferenceMatchesDefinition(a.GetName(), dynamicAssemblyName))); |
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.
I think it should make use of the assemblyBuilder outside of the using block - just to be on the safe side. Otherwise the compiler/JIT can throw it away before it gets to the validation.
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.
Fixed
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 - Thanks a lot!
I restarted some of the CI legs as there were issues with AzDo. |
You can ignore the "pgo" failures -- for a short time these new pipelines were running on all PRs. |
Thank @Ap0k for the fix! |
Fix issue #48579