Skip to content

Conversation

@CoffeeFlux
Copy link
Contributor

@CoffeeFlux CoffeeFlux commented Sep 18, 2020

Manual backport of #42425 to to release/5.0-rc2

Customer Impact

Without this fix, custom ALCs are are somewhat broken on wasm when using the bundle. Any reference from an assembly in a custom ALC will not check the default ALC to see if that assembly is already loaded there, and will instead load a new copy of the assembly into the custom ALC. This means types won't be linked and you can get multiple copies of common assemblies unintentionally. The added test highlights some of the ways this can break customer code, and of particular note is the fact that Assembly.Load(byte[]) creates a new ALC, so this is actually a regression from 3.2.

Testing

A new test was added to catch this specific regression, and the existing ALC tests should still pass.

Risk

Moderate. While this is making a change to the loading algorithm, it's wasm-specific, straightforward, and fixes previously broken behavior. With that said, it is possible that code was unintentionally relying on that broken behavior (which is why some of our tests were passing that shouldn't have, for example).

I believe this to be worth the risk, since the type decoupling makes custom ALCs borderline unusable in a lot of scenarios and regresses Assembly.Load.

cc: @marek-safar @SamMonoRT

@CoffeeFlux CoffeeFlux added Servicing-consider Issue for next servicing release review area-AssemblyLoader-mono labels Sep 18, 2020
@CoffeeFlux CoffeeFlux added this to the 5.0.0 milestone Sep 18, 2020
@ghost
Copy link

ghost commented Sep 18, 2020

Tagging subscribers to this area: @CoffeeFlux
See info in area-owners.md if you want to be subscribed.

@CoffeeFlux CoffeeFlux added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Sep 18, 2020
@CoffeeFlux
Copy link
Contributor Author

Approved by tactics via email, but still need a review. cc: @lambdageek

Copy link
Contributor

@pranavkm pranavkm left a comment

Choose a reason for hiding this comment

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

Test looks great.

public class LoaderLinkTest
{
[Fact]
public static void EnsureTypesLinked() // https://github.com/dotnet/runtime/issues/42207
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I'm not very familiar with the language in the loader so feel free to ignore this. The current name sounds like it's talking about the trimmer \ linker. Should we call this EnsureAssembliesAreLoadedFromTheDefaultLoadContext or something along those lines?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's mostly fine? The idea is that we want to ensure you're referencing the same type, and 'linked' is a common way to refer to that.

}

if (bundles != NULL && is_satellite) {
// Satellite assembly byname requests should be loaded in the same ALC as their parent assembly
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think this warrants a test?

Copy link
Contributor Author

@CoffeeFlux CoffeeFlux Sep 18, 2020

Choose a reason for hiding this comment

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

We have a suite of tests for that already, they were just previously passing for the wrong reasons due to the old, bad behavior. I'm planning to update a bunch of our loader tests next week to try and catch this stuff throughout, as well as get the DefaultContext test running on wasm. See my last email to tactics (can forward if you aren't subscribed).

Assert.Equal(typeof(ISharedInterface), sharedInterface);

var instance = Activator.CreateInstance(dynamicType);
Assert.True(instance is ISharedInterface);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Assert.True(instance is ISharedInterface);
Assert.IsAssignableFrom<ISharedInterface>(instance);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, good catch. I don't really want to run through CI again just for this, but I'll fix this as part of my updates to the tests next week.

Copy link
Member

@lambdageek lambdageek left a comment

Choose a reason for hiding this comment

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

netcore_load_reference lgtm

so together with the test, this looks good

@CoffeeFlux CoffeeFlux merged commit 8b1f309 into dotnet:release/5.0-rc2 Sep 21, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants