-
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
TypeLoadException from dynamically-generated assembly; does not occur from the same assembly loaded from disc #63294
Comments
Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov Issue DetailsDescriptionWhile testing the Boo compiler's System.Reflection.Metadata port, I ran across a very strange error. When creating two assemblies in-memory, Both assemblies pass ILVerify, and the process works just fine when loaded from disc. This suggests that the problem is not in the assemblies, but rather the runtime. Either that or there's some obscure corner case with my code generation? Reproduction Steps
Expected behaviorIn both cases, the same output should be generated. Actual behaviorStep 5 works as expected, but step 3 crashes. Regression?This worked as expected under Framework when generating the assemblies with System.Reflection.Emit. Known WorkaroundsNo response Configuration.NET 5, Windows 10, x64 Other informationIt would be a lot easier to debug this if
|
how do you load the assemblies? note metadata doesn't load. |
@webczat Code for loading generated assembly in memory. Also, code for saving assembly to disc, in case it's relevant. They're basically the same thing, except in one case the PE blob bytes get written to a file, and in the other they get passed to |
@jkotas @MichalStrehovsky Ping! This issue may or may not be more relevant to you guys than to the people msftbot pinged. |
not fully sure how that loading works when it goes to dependency loading, but: |
Not a problem here. The first assembly gets built in-memory, then runs. It calls into the compiler to build the second one and sets itself as a dependency of the second one, which it's building.
According to this page, "assemblies that are loaded from byte arrays are loaded without context unless their identity (after policy is applied) establishes that they are in the global assembly cache." (Which doesn't apply here.) So if both of them are "loaded without context," what are the implications? |
i don't mean these contexts. although this doc suggests your use case should work so someone else could comment on that. AssemblyLoadContext is a completely new dotnet core concept. |
I am observing "System.IO.FileNotFoundException: Could not load file or assembly 'testcase...`.
Correct, assemblies loaded from byte arrays always go into own context in .NET Core. The documentation says "Other assemblies cannot bind to assemblies that are loaded without context, unless you handle the AppDomain.AssemblyResolve event.". Are you handling the AssemblyResolve event to somewhere in your test harness? |
Weird! What's the stack trace?
I just tried adding the following to the run code:
Placing a breakpoint in the body of |
@jkotas Very strange. Here's what I'm getting:
Very similar to yours, but breaking for a different reason. It looks like you have the generated assembly loaded, from the line mentioning |
I do see I am running the repro on .NET Core 5.0.12. What is the exact runtime version that the test is running on your machine? |
@jkotas OK, I just found the discrepancy. Apparently I had an old version of My assembly resolver is still never being called, though. You can verify this in |
The version number in the error message looks odd: |
That's actually correct. It shows up in the version metadata if you decompile it with ILDASM and look at the MANIFEST. This appears to be the default; figuring out how to get SRM to produce a better version number is on the to-do list. |
well that is the thing I can tell you.. version number is always x.x.x.x so it fills missing pieces. 📦 |
So why does it fill in the first two with 0 and the last two with -1 by default? And how do I plug in my own numbers? It kinda looks like they should go in |
aaaah. no no it's not pe builder, it's assembly manifest. add a correct entry to the assembly table, the AddAssembly method has a version parameter. |
OK, after changing that to use |
Can you try again? The AssemblyResolve event is getting hit for me. |
Bleh. Thanks for the help. It was running afterall; not sure why the breakpoint wasn't triggering. Must be Visual Studio being flaky. I've been able to resolve this locally. |
Description
While testing the Boo compiler's System.Reflection.Metadata port, I ran across a very strange error. When creating two assemblies in-memory,
A
andB
, whereA
is created first andB
has a dependency on it, ifB
attempts to load anAttribute
defined onA
, it will throw aTypeLoadException
. However, if both assemblies are saved to disc and loaded as project references of assemblyC
, all the types load as expected.Both assemblies pass ILVerify, and the process works just fine when loaded from disc. This suggests that the problem is not in the assemblies, but rather the runtime. Either that or there's some obscure corner case with my code generation?
Reproduction Steps
TypeLoadException
being thrown when it tries to access theVarArgsAttribute
class.Expected behavior
In both cases, the same output should be generated.
Actual behavior
Step 5 works as expected, but step 3 crashes.
Regression?
This worked as expected under Framework when generating the assemblies with System.Reflection.Emit.
Configuration
.NET 5, Windows 10, x64
Other information
It would be a lot easier to debug this if
TypeLoadException
would provide some relevant information regarding what went wrong.The text was updated successfully, but these errors were encountered: