-
-
Notifications
You must be signed in to change notification settings - Fork 619
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
Stack overflow resolving TypeReference #573
Comments
Thanks for reporting this! |
Confirm that the issue is the same, when resolution of type reach Search
Try to find on
Try to find on
But you're on netcoreapp where System.Collections.Generic.ISet1 (
And so on. public class PublishedAssemblyResolver : DefaultAssemblyResolver
{
public PublishedAssemblyResolver(string assemblyPath)
{
AddSearchDirectory(Path.GetDirectoryName(assemblyPath));
}
public override AssemblyDefinition Resolve(AssemblyNameReference name)
{
if (name.FullName == "netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")
{
return AssemblyDefinition.ReadAssembly(Path.Combine(Path.GetDirectoryName(typeof(object).Assembly.Location), Path.ChangeExtension(name.Name, ".dll")));
}
else
{
return base.Resolve(name);
}
}
} or first load always from "shared" framework(gac or shared) public class PublishedAssemblyResolver : DefaultAssemblyResolver
{
public PublishedAssemblyResolver(string assemblyPath)
{
AddSearchDirectory(Path.GetDirectoryName(typeof(object).Assembly.Location));
AddSearchDirectory(Path.GetDirectoryName(assemblyPath));
}
} |
@MarcoRossignoli cheers for the info - have been having a poke around with your reproducer and been finding the same things. I tried a workaround similar to the first you suggested, although checking when the only The most robust solution I've found is to recursively add the subfolders from the GAC (under |
FYI I'm trying to understand if "netstandard aware" resolver works well https://github.com/tonerdo/coverlet/pull/370/files#diff-b37379a034734abdfbec0ec6585cdfb7R630 |
@jbevain we are using Cecil for Mirror, our Unity networking library based on their old UNET. Edit: sorry for quadruple post, Github was bugged. |
Thanks to everybody who's looking at this. My understanding of the issue lies in the very first The I'm not sure there's a good solution here. If you're going to write a .NET Core program that can work on .NET Framework assemblies, the |
agree with @jbevain on
this was my finding when writing Fody. assembly resolution is very specific to the context cecil is being run from. DefaultAssemblyResolver does a pretty good job for many scenarios, but it is not possible for it to cover all context/use cases that cecil can be run from |
Yep on coverlet custom resolver seems to work well. |
Closing this as per #573 (comment) I'm not sure the default resolver could do a lot more for those mixed scenarios. Thanks! |
In certain scenarios where a type implements an interface in another assembly, attempting to resolve the
TypeReference
to the interface results in an infinite loop and a stack overflow.This is an issue I encountered with a real application with fairly complex dependencies - I've been struggling to find a simple repro that copies the right dlls in, but it's possible to manually copy them to the bin folder to reproduce.
The issue occurs when the build copies the following dlls to the bin dir:
The latter two get copied in when you have a net framework assembly which references a net standard assembly (as per some of the details in https://github.com/dotnet/corefx/issues/26456).
You can see the issue by creating a net461 library with a single type implementing
ISet<string>
(e.g. https://github.com/r-bennett/MonoCecilRepro/blob/master/ClassLibrary1/Class1.cs), building the library, manually copying the above dlls to the bin folder, then attempting to load the type and resolve its interface, something like:Each of the 3 dlls mentioned above has only a single type (
<Module>
) listed on it when read with Mono Cecil, with all the expected types appearing only in exportedTypes. The issue seems to be related to net standard's assembly unification (https://github.com/dotnet/standard/blob/315834b5eaa426ed37f6a767f15cf1d5eb7b4a85/docs/planning/netstandard-2.0/README.md#assembly-unification), although I'm not quite sure what's going on here.The infinite loop occurs with
MetadataResolver.Resolve(TypeReference)
- it tries to resolve theISet
interface first withnetstandard.dll
, then withSystem.dll
, then withSystem.Runtime.dll
, then looping back tonetstandard.dll
when it can't find it in the types of any of those modules.I'm happy to put some time into resolving this, but I'm not sure what the correct resolution behaviour should be here.
The text was updated successfully, but these errors were encountered: