-
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
Assertion failed in assemblybinder.cpp, line 1833 #6163
Comments
If an app has a static assembly reference to an assembly that is missing (which is not the normal case since .NET Core app have their dependencies complete) OR attempts to do Assembly.Load against an assembly that is missing AND has wired up to the Resolving event to load the assemblies from custom locations, then the event will not return a valid reference and could result in a crash. The workaround to address the above problem is one of the following: Load the assembly using LoadFromAssemblyName instead of Assembly.Load, OR |
@tmat Given that there are two workarounds, this should not be blocking until the formal fix comes through. Does that sound good to you? |
@gkhanna79 Sounds good. |
Reopening until tests are updated as well. |
Test added in CoreFX via dotnet/corefx#9639 |
…016. Corresponds to dotnet#6611 [tfs-changeset: 1621298]
…016. Corresponds to dotnet#6611 [tfs-changeset: 1621298]
…016. Corresponds to dotnet#6611 [tfs-changeset: 1621298]
We are required to preload System.Runtime.Serialization.Primitives since it is used for serialization by Newtonsoft.Json. Failure to do so results in an EngineExecutionException because of https://github.com/dotnet/coreclr/issues/5837, which should be fixed in a post-RTM release.
Related to issue dotnet#750. We need the ability to load task-containing assemblies from arbitrary locations on disk determined at run time, along with thei dependencies. It is assumed that their dependencies will be located next to them in the file system, or in some well-known location. Ideally we would handle the dependencies by hooking the `Resolving` event on the default `AssemblyLoadContext`. However, due to https://github.com/dotnet/coreclr/issues/5837 we can't currently do this. Instead, we need to implement our own `AssemblyLoadContext`. This is what we currently do. However, we run into a problem when a task assembly depends on, say, Microsoft.Build.dll (which is pretty much guaranteed). Microsoft.Build will already be loaded into the default `AssemblyLoadContext`, but since our task assembly was loaded into *our* context, we are likely to be asked to load it again when the task needs it. We currently handle this by looking for it in the app's base directory, which seems like a good bet. So we may end up loading this assembly twice, in two different contexts--not great, but everything still works. Issue dotnet#750 comes into play when Microsoft.Build.dll has been CrossGen'd to a native assembly. Both contexts will find and try to load the native assembly--and this is currently not allowed. So to work around these other issues in assembly loading, we need to maintain our own `AssemblyLoadContext` for the time being. However, we now ask the default `AssemblyLoadContext` to first try satisfying the load. If it succeeds, the load will occur in that context. Only if it can't find the assembly in question do we attempt to find and load the assembly ourselves (putting it in our context).
Related to issue dotnet#750. We need the ability to load task-containing assemblies from arbitrary locations on disk determined at run time, along with their dependencies. It is assumed that their dependencies will be located next to them in the file system, or in some well-known location. Ideally we would handle the dependencies by hooking the `Resolving` event on the default `AssemblyLoadContext`. However, due to https://github.com/dotnet/coreclr/issues/5837 we can't currently do this. Instead, we need to implement our own `AssemblyLoadContext`. Indeed, this is what we currently do. However, we run into a problem when a task assembly depends on, say, Microsoft.Build.dll (which is pretty much guaranteed). Microsoft.Build will already be loaded into the default `AssemblyLoadContext`, but since our task assembly was loaded into *our* context, we are likely to be asked to load it again when the task needs it. We currently handle this by looking for it in the app's base directory, which seems like a good bet. So we may end up loading this assembly twice, in two different contexts--not great, but everything still works. Issue dotnet#750 comes into play when Microsoft.Build.dll has been CrossGen'd to a native assembly. Both contexts will find and try to load the native assembly--and this is currently not allowed. So to work around these other issues in assembly loading, we need to maintain our own `AssemblyLoadContext` for the time being. However, we now ask the default `AssemblyLoadContext` to first try satisfying the load. If it succeeds, the load will occur in that context. If it fails, we'll get an exception. Either the default context couldn't locate an assembly with the given name, or located what *should* have been the assembly but wasn't actually (e.g., a native file with the same name, or a corrupted file) or may couldn't read the file due to permission issues. If this occurs, we simply catch and swallow the exception, and then attempt to find and load the assembly ourselves, putting it in our context. We could think about letting some of these through. For example, if the default context located the assembly but couldn't read it (BadImageFormatException or an exception representing a permission issue) then it would probably be better to let that exception propagate rather than catch or ignore it. It's not clear where we would draw the line, though, and since this whole approach is a workaround for other runtime issues I'd rather just keep it as simple as possible.
The only reason we implemented our own `AssemblyLoadContext` was to work around https://github.com/dotnet/coreclr/issues/5837. That bug prevented us from helping the default `AssemblyLoadContext` find assemblies by hooking the `Resolving` event; the only other way to get them loaded was to do it ourselves. This workaround has its own problems. Since we've got two different load contexts, it is entirely possible that the same assembly will be loaded twice: once in each. That isn't great, but it works--except for crossgen'd assemblies due to https://github.com/dotnet/coreclr/issues/6695. For performance reasons, the dotnet CLI crossgens many if not all of the assemblies it loads, so it runs into problems all the time. So now that https://github.com/dotnet/coreclr/issues/5837 is fixed we can simplify things by getting rid of our `AssemblyLoadContext` and simply hooking the `Resolving` event. This will avoid double loads and thus avoid https://github.com/dotnet/coreclr/issues/6695.
When loading analyzer assemblies on CoreCLR on Mac/Linux we hit a segmentation fault. Running on the debug build of the Core CLR from master reports an assert:
debug build
release build:
The text was updated successfully, but these errors were encountered: