Skip to content
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

Merged
merged 1 commit into from
May 28, 2021
Merged

Fix #48579 #49387

merged 1 commit into from
May 28, 2021

Conversation

Ap0k
Copy link
Contributor

@Ap0k Ap0k commented Mar 9, 2021

Fix issue #48579


using (assemblyLoadContext.EnterContextualReflection())
{
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(dynamicAssemblyName, assemblyBuilderAccess);
assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(dynamicAssemblyName, assemblyBuilderAccess);
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

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?

Copy link
Contributor Author

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.

@kunalspathak
Copy link
Member

Please revert the change in #50592 as part of this PR.

@Ap0k
Copy link
Contributor Author

Ap0k commented Apr 20, 2021

@kunalspathak Who else can review this PR?

@kunalspathak
Copy link
Member

@kunalspathak Who else can review this PR?

@stephentoub has already reviewed and asked question. Could you please answer and suggest a better fix?

@Ap0k
Copy link
Contributor Author

Ap0k commented May 11, 2021

@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.

@kunalspathak
Copy link
Member

@Ap0k - Sorry for the delay. I have started various CI stress pipelines which will verify if your fix works.

@Ap0k
Copy link
Contributor Author

Ap0k commented May 11, 2021

@kunalspathak Okay. Waiting for test results.

@Ap0k
Copy link
Contributor Author

Ap0k commented May 11, 2021

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.

@kunalspathak
Copy link
Member

@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.

set COMPlus_TieredCompilation=0
set COMPlus_GCStress=0xC

Let me know if you need anything else.

@Ap0k
Copy link
Contributor Author

Ap0k commented May 11, 2021

Let me know if you need anything else.

Is it necessary to somehow change the configuration in testmix_gc.config?

@kunalspathak
Copy link
Member

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.

@Ap0k
Copy link
Contributor Author

Ap0k commented May 12, 2021

  1. Fixed a bug with the definition of ALC for dynamic assembly;
  2. The test logic has been changed. Now, instead of searching for an assembly in ALC by its name, its load context is determined and compared with the reference one.

Local test results:

=== TEST EXECUTION SUMMARY ===
   baseservices.compilerservices.XUnitWrapper           Total:   2, Errors: 0, Failed: 0, Skipped: 0, Time:    8,620s
   baseservices.exceptions.XUnitWrapper                 Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:   67,907s
   baseservices.TieredCompilation.XUnitWrapper          Total:  13, Errors: 0, Failed: 0, Skipped: 0, Time:   52,867s
   baseservices.typeequivalence.XUnitWrapper            Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    4,692s
   baseservices.varargs.XUnitWrapper.dll                Total:   0
   CoreMangLib.system.XUnitWrapper                      Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    3,572s
   Exceptions.ForeignThread.XUnitWrapper                Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    3,959s
   GC.API.XUnitWrapper                                  Total:  32, Errors: 0, Failed: 0, Skipped: 0, Time:  199,606s
   GC.Coverage.XUnitWrapper                             Total:   2, Errors: 0, Failed: 0, Skipped: 0, Time:    8,613s
   GC.Features.XUnitWrapper                             Total:  21, Errors: 0, Failed: 0, Skipped: 0, Time:  186,054s
   GC.LargeMemory.XUnitWrapper                          Total:   3, Errors: 0, Failed: 0, Skipped: 0, Time:    6,566s
   GC.Regressions.XUnitWrapper                          Total:  10, Errors: 0, Failed: 0, Skipped: 0, Time:   20,874s
   GC.Scenarios.XUnitWrapper                            Total:  37, Errors: 0, Failed: 0, Skipped: 0, Time:  233,191s
   GC.Stress.XUnitWrapper                               Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    0,347s
   ilasm.PortablePdb.XUnitWrapper                       Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:   17,226s
   ilasm.System.XUnitWrapper                            Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    7,005s
   Loader.AssemblyDependencyResolver.XUnitWrapper       Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    4,798s
   Loader.AssemblyLoadContext30Extensions.XUnitWrapper  Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    3,580s
   Loader.binding.XUnitWrapper                          Total:   2, Errors: 0, Failed: 0, Skipped: 0, Time:  101,780s
   Loader.CollectibleAssemblies.XUnitWrapper            Total:   2, Errors: 0, Failed: 0, Skipped: 0, Time:    4,069s
   Loader.ContextualReflection.XUnitWrapper             Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    5,234s
   Loader.regressions.XUnitWrapper                      Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    3,575s
   managed.Compilation.XUnitWrapper                     Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:   74,885s
   readytorun.coreroot_determinism.XUnitWrapper         Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:  418,934s
   readytorun.crossgen2.XUnitWrapper                    Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    8,234s
   readytorun.determinism.XUnitWrapper                  Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:   77,236s
   readytorun.DynamicMethodGCStress.XUnitWrapper.dll    Total:   0
   readytorun.r2rdump.XUnitWrapper                      Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:   19,578s
   readytorun.tests.XUnitWrapper                        Total:   3, Errors: 0, Failed: 0, Skipped: 0, Time:    5,054s
   reflection.DefaultInterfaceMethods.XUnitWrapper      Total:   3, Errors: 0, Failed: 0, Skipped: 0, Time:    3,812s
   reflection.Modifiers.XUnitWrapper                    Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    3,600s
   reflection.RefEmit.XUnitWrapper                      Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    3,787s
   reflection.regression.XUnitWrapper                   Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    3,420s
   reflection.SetValue.XUnitWrapper                     Total:   2, Errors: 0, Failed: 0, Skipped: 0, Time:    5,323s
   reflection.StaticInterfaceMembers.XUnitWrapper       Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    3,465s
   Regressions.coreclr.XUnitWrapper                     Total:  23, Errors: 0, Failed: 0, Skipped: 0, Time:   15,006s
   tracing.eventactivityidcontrol.XUnitWrapper          Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    3,641s
   tracing.eventcounter.XUnitWrapper                    Total:   7, Errors: 0, Failed: 0, Skipped: 0, Time:    0,699s
   tracing.eventlistener.XUnitWrapper                   Total:   1, Errors: 0, Failed: 0, Skipped: 0, Time:    3,748s
   tracing.eventpipe.XUnitWrapper                       Total:  13, Errors: 0, Failed: 0, Skipped: 0, Time:   12,297s
                                                               ---          -          -           -        ---------
                                                  GRAND TOTAL: 197          0          0           0        1606,854s (1618,440s)

@kunalspathak
Copy link
Member

I have kicked off another GCStress run.

  • Fixed a bug with the definition of ALC for dynamic assembly;

I do not fully understand this fix and might need to check with @stephentoub on what he thinks.

  • The test logic has been changed. Now, instead of searching for an assembly in ALC by its name, its load context is determined and compared with the reference one.

Why is the test changed? Was earlier the test was not validating the appropriate behaviour?

@Ap0k
Copy link
Contributor Author

Ap0k commented May 13, 2021

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.
That is why we had to fix the mentioned error and correct the logic of the test. Since it is quite logical that if we check the creation of a dynamic assembly for the selected ALC, then it is easier and faster after its creation to try to find it in this ALC, and not iterate over all assemblies from the context.

@Ap0k
Copy link
Contributor Author

Ap0k commented May 13, 2021

@kunalspathak what are the test results? I see from the logs that the test we are interested in has passed :)

@kunalspathak
Copy link
Member

@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?

@Ap0k
Copy link
Contributor Author

Ap0k commented May 13, 2021

@kunalspathak Ok, I'll check

@kunalspathak
Copy link
Member

kunalspathak commented May 13, 2021

@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?

@Ap0k
Copy link
Contributor Author

Ap0k commented May 24, 2021

@kunalspathak Who else can review this PR?

@kunalspathak
Copy link
Member

@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);
Copy link
Member

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 in AppDomain.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.

Copy link
Contributor Author

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.

Copy link
Member

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.

Copy link
Contributor Author

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));
Copy link
Member

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?

Copy link
Contributor Author

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).

Copy link
Contributor Author

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.

@Ap0k Ap0k requested a review from vitek-karas May 26, 2021 18:56

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)));
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

Copy link
Member

@vitek-karas vitek-karas left a 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!

@vitek-karas
Copy link
Member

I restarted some of the CI legs as there were issues with AzDo.

@AndyAyersMS
Copy link
Member

You can ignore the "pgo" failures -- for a short time these new pipelines were running on all PRs.

@vitek-karas vitek-karas merged commit c6ef760 into dotnet:main May 28, 2021
@vitek-karas
Copy link
Member

Thank @Ap0k for the fix!

@ghost ghost locked as resolved and limited conversation to collaborators Jun 27, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants