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

[Unhandled Exception]: System.ObjectDisposedException: This object is no longer valid because the MetadataLoadContext that created it has been disposed. #11242

Open
pavelsavara opened this issue Jan 8, 2025 · 5 comments

Comments

@pavelsavara
Copy link
Member

pavelsavara commented Jan 8, 2025

Issue Description

Log

[] MSBUILD : error MSB4166: UNHANDLED EXCEPTIONS FROM PROCESS 1842:
[] MSBUILD : error MSB4166: =====================
[] MSBUILD : error MSB4166: 1/7/2025 5:29:23 PM
[] MSBUILD : error MSB4166: System.ObjectDisposedException: This object is no longer valid because the MetadataLoadContext that created it has been disposed.
[] MSBUILD : error MSB4166:    at System.Reflection.MetadataLoadContext.DisposeCheck()
[] MSBUILD : error MSB4166:    at System.Reflection.TypeLoading.Ecma.EcmaDefinitionType.ComputeDeclaringType()
[] MSBUILD : error MSB4166:    at System.Reflection.TypeLoading.RoType.get_DeclaringType()
[] MSBUILD : error MSB4166:    at System.Reflection.TypeLoading.RoDefinitionType.ComputeFullName()
[] MSBUILD : error MSB4166:    at System.Reflection.TypeLoading.RoType.get_FullName()
[] MSBUILD : error MSB4166:    at Microsoft.Build.Framework.LazyFormattedBuildEventArgs.WriteToStream(BinaryWriter writer)
[] MSBUILD : error MSB4166:    at Microsoft.Build.Framework.BuildMessageEventArgs.WriteToStream(BinaryWriter writer)
[] MSBUILD : error MSB4166:    at Microsoft.Build.Shared.LogMessagePacketBase.WriteToStream(ITranslator translator)
[] MSBUILD : error MSB4166:    at Microsoft.Build.BackEnd.NodeEndpointOutOfProcBase.RunReadLoop(Stream localReadPipe, Stream localWritePipe, ConcurrentQueue`1 localPacketQueue, AutoResetEvent localPacketAvailable, AutoResetEvent localTerminatePacketPump)
[] MSBUILD : error MSB4166: ===================

Steps to Reproduce

I don't know how to reproduce.
It happened only once AFAIK during Wasm.Build.Tests.PInvokeTableGeneratorTests of dotnet/runtime build.

Since it happened on Helix machine I also don't have the detailed log.

mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-webassembly on a002M0D

.NET SDK Version: 10.0.100-alpha.1.24622.2

Actual Behavior

No exception

Analysis

No response

Versions & Configurations

No response

@pavelsavara
Copy link
Member Author

It's quite possible that there is parent msbuild process and multiple child msbuild processes running in parallel

@JanKrivanek
Copy link
Member

Thank you @pavelsavara for reporting!

On a first look it doesn't seem like msbuild would do anything wrong here - this seems to go from the type system.

@janvorli - would you be able to suggest who should have a look here?

@janvorli
Copy link
Member

janvorli commented Jan 9, 2025

@davidwrighton do you have any thoughts on this?

@davidwrighton
Copy link
Member

I don't see any way for it looks to me like the call to Convert.ToString(...) in the LazyFormattedBuildEventArgs.WriteToStream tail-called the ToString() function on an instance of RoDefinitionType, and the implementation of THAT function has tail-called RoType.FullName, and the actual MetadataLoadContext has been disposed. For whatever reason. My guess would be that the laziness here is causing a problem, and what's happening is that MetadataLoadContext is relying on a finalizer or something to trigger its Dispose, and the current codebase in msbuild which does this lazy error generation is just happening to get unlucky. If code is stuffing a RoDefinitionType (or any other RoType derived object) as a lazy argument this could happen. The fix would be to go to the code which calls the constructor of the LazyFormattedBuildEventArgs with a set of arguments which includes one of these types which cannot safely be used lazily, and to call ToString() then and there instead of having this code do the lazy handling. Alternatively, one could fix this by having msbuild have an allow list of types on which can ToString() can safely be called lazily, and eagerly call ToString() for cases where safety isn't known. Of course, all of this is speculation. I can't be confident in knowing if that is what actually happened without some sort of crash dump.

@davidwrighton
Copy link
Member

We could probably check to see if this is what is happening by building a custom copy of msbuild, that looked for creation of LazyFormattedBuildEventArgs holding as arguments instances of types from System.Reflection.MetadataLoadContext, and then triggering this build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants