dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.71k stars 3.98k forks source link

MEF and Workspaces crash with ReflectionTypeLoadException on Mono #20275

Open praeclarum opened 7 years ago

praeclarum commented 7 years ago

Version Used: 2.2.0

Steps to Reproduce:

  1. Create a new console app in Visual Studio for Mac Beta (7.0.1 b24, but it doesn't really matter, this bug is ancient)
  2. Reference Microsoft.CodeAnalysis 2.2.0 (again, version doesn't matter)
  3. Add this line: var workspace = MSBuildWorkspace.Create();
  4. Run the code

Expected Behavior: A new workspace object is created

Actual Behavior: Crash!

System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
  at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (System.Reflection.Assembly,bool)
  at System.Reflection.Assembly.GetTypes () [0x00000] in /private/tmp/source-mono-2017-02/bockbuild-2017-02/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/corlib/System.Reflection/Assembly.cs:410 
  at System.Reflection.Assembly+<get_DefinedTypes>d__150.MoveNext () [0x0001e] in /private/tmp/source-mono-2017-02/bockbuild-2017-02/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/corlib/System.Reflection/Assembly.cs:1019 
  at System.Linq.Enumerable+SelectEnumerableIterator`2[TSource,TResult].MoveNext () [0x00029] in /private/tmp/source-mono-2017-02/bockbuild-2017-02/profiles/mono-mac-xamarin/build-root/mono-x86/external/corefx/src/System.Linq/src/System/Linq/Select.cs:133 
  at System.Linq.Enumerable+SelectManySingleSelectorIterator`2[TSource,TResult].MoveNext () [0x0006f] in /private/tmp/source-mono-2017-02/bockbuild-2017-02/profiles/mono-mac-xamarin/build-root/mono-x86/external/corefx/src/System.Linq/src/System/Linq/SelectMany.cs:209 
  at System.Composition.TypedParts.TypedPartExportDescriptorProvider..ctor (System.Collections.Generic.IEnumerable`1[T] types, System.Composition.Convention.AttributedModelProvider attributeContext) [0x00049] in <c091afde214c4b8e8efbbeb9d44062d4>:0 
  at System.Composition.Hosting.ContainerConfiguration.CreateContainer () [0x00042] in <c091afde214c4b8e8efbbeb9d44062d4>:0 
  at Microsoft.CodeAnalysis.Host.Mef.MefHostServices.Create (System.Collections.Generic.IEnumerable`1[T] assemblies) [0x0001e] in <7f0d4b9d7a9a40cfa302b8c61f11defa>:0 
  at Microsoft.CodeAnalysis.Host.Mef.DesktopMefHostServices.get_DefaultServices () [0x00011] in <43494904657a4fb99e35e930a2c70ef9>:0 
  at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create (System.Collections.Generic.IDictionary`2[TKey,TValue] properties) [0x00000] in <43494904657a4fb99e35e930a2c70ef9>:0 
  at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create () [0x00000] in <43494904657a4fb99e35e930a2c70ef9>:0 
  at TestRoslyn.MainClass.Main (System.String[] args) [0x00001] in /Users/fak/Projects/TestRoslyn/Program.cs:11 

When I first talked about this bug on Twitter years ago, a mono community member knew what the issue was - something about loading rules for assemblies. Unfortunately, I cannot remember the details and twitter search is failing me.

I worked around this bug for years by simply not using the Workspace feature. It's been hard. I would love to have this working.

terrajobst commented 7 years ago

@marek-safar @akoeplinger are you aware of issues with using MEFv2 (System.Composition) on Mono?

Pilchie commented 7 years ago

Note that @mhutch uses MEF in VS4Mac on Mono, and @DustinCampbell does for Omnisharp-roslyn so I don't think that's it. This may be something specific to MSBuildWorkspace.

terrajobst commented 7 years ago

Do VS4Mac or OmniSharp use the MSBuildWorkspace?

Pilchie commented 7 years ago

Do VS4Mac or OmniSharp use the MSBuildWorkspace?

Not AFAIK.

praeclarum commented 7 years ago

Sorry to hop in, but is there an alternative to MSBuildWorkspace? I don't see any others in the box. Or are you saying VSM wrote their own?

Pilchie commented 7 years ago

Yes, VSM wrote it's own. MSBuildWorkspace has very limited support for modifying things/hosting in an editor/etc. It's mostly there for writing static analysis type tools.

praeclarum commented 7 years ago

Oh funny, I tried to write my own too but ran into trouble with internal interfaces. However, that was ancient Roslyn and I haven't tried since. Good to know others have achieved it.

nosami commented 7 years ago

OmniSharp has it's own workspace implementations too.

terrajobst commented 7 years ago

@nosami: how does OmniSharp parse the project files? Does it evaluate the project and properties to get the correct data or does it guess / expose the file system?

Pilchie commented 7 years ago

See https://github.com/OmniSharp/omnisharp-roslyn/blob/beb61b8683c382c498c62556f8fa7ace43631cf7/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs

marek-safar commented 7 years ago

@terrajobst no and this does not look like MEF specific bug more like Mono reflection issue. @praeclarum could you please fill a bug report with repro so we can quickly test if we can reproduce it.

praeclarum commented 7 years ago

@marek-safar I filed: https://bugzilla.xamarin.com/show_bug.cgi?id=57568 with an attached repro.

Pilchie commented 7 years ago

Giving to @DustinCampbell for now, since he's currently the most knowledgeable about Workspaces on .NET Core and Mono that we've got.

Note that the xamarin bugzilla has:

Running with MONO_LOG_LEVEL=debug prints this:

Mono: The following assembly referenced from /Users/vargaz/Projects/57568/TestRoslyn/bin/Debug/Microsoft.CodeAnalysis.Workspaces.Desktop.dll could not be loaded:
     Assembly:   Microsoft.Build.Tasks.Core    (assemblyref_index=9)
     Version:    15.1.0.0
     Public Key: b03f5f7f11d50a3a
The assembly was not found in the Global Assembly Cache, a path listed in the MONO_PATH environment variable, or in the location of the executing assembly (/Users/vargaz/Projects/57568/TestRoslyn/bin/Debug/).
Pilchie commented 7 years ago

Note - I get the same errors with a default project on windows, with MSBuild not in the gac. I had to add packages for Microsoft.Build and Microsoft.Build.Tasks.Core (v 15.1.1012).

aka-STInG commented 7 years ago

I have this packages added and I have the same ReflectionTypeLoadException

Pilchie commented 7 years ago

@aka-STInG on Mono, or on Windows?

aka-STInG commented 7 years ago

On Mono on Mac

praeclarum commented 7 years ago

Looking at https://github.com/dotnet/roslyn/blob/master/src/Workspaces/Core/Desktop/Workspaces.Desktop.csproj

I see that there is a reference to https://www.nuget.org/packages/Microsoft.Build.Tasks.Core

However, when I restore, Microsoft.Build.Tasks.Core is not downloaded.

Following this chain:

I don't ever see Microsoft.Build.Tasks.Core

So is this a nuget packaging issue?

lambdageek commented 7 years ago

When I add Microsoft.Build and Microsoft.Build.Tasks.Core (v15.1.1012) the DEBUG output is different than the original report:

...
Mono: The following assembly referenced from /Users/alekseyk/work/bugs/57568/TestRoslyn/bin/Debug/Microsoft.CodeAnalysis.Workspaces.Desktop.dll could not be loaded:
     Assembly:   Microsoft.VisualStudio.RemoteControl    (assemblyref_index=14)
     Version:    14.0.0.0
     Public Key: b03f5f7f11d50a3a
The assembly was not found in the Global Assembly Cache, a path listed in the MONO_PATH environment variable, or in the location of the executing assembly (/Users/alekseyk/work/bugs/57568/TestRoslyn/bin/Debug/).

Mono: Failed to load assembly Microsoft.CodeAnalysis.Workspaces.Desktop[0x7fe336701ec0].
Could not load signature of Microsoft.CodeAnalysis.SymbolSearch.SymbolSearchUpdateEngine+RemoteControlService:CreateClient due to: Could not load file or assembly 'Microsoft.VisualStudio.RemoteControl, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. assembly:Microsoft.VisualStudio.RemoteControl, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a type:<unknown type> member:<none>
Could not load signature of Microsoft.CodeAnalysis.SymbolSearch.IRemoteControlService:CreateClient due to: Could not load file or assembly 'Microsoft.VisualStudio.RemoteControl, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. assembly:Microsoft.VisualStudio.RemoteControl, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a type:<unknown type> member:<none>

Unhandled Exception:
System.TypeLoadException: Could not resolve the signature of a virtual method
  at (wrapper managed-to-native) System.RuntimeType:GetPropertiesByName_native (System.RuntimeType,intptr,System.Reflection.BindingFlags,bool)
  at System.RuntimeType.GetPropertiesByName (System.String name, System.Reflection.BindingFlags bindingAttr, System.Boolean icase, System.RuntimeType reflectedType) [0x0001b] in <2ffe54eb3b79405792636f3ca93458bd>:0 
  at System.RuntimeType.GetPropertyCandidates (System.String name, System.Reflection.BindingFlags bindingAttr, System.Type[] types, System.Boolean allowPrefixLookup) [0x00010] in <2ffe54eb3b79405792636f3ca93458bd>:0 
  at System.RuntimeType.GetProperties (System.Reflection.BindingFlags bindingAttr) [0x00000] in <2ffe54eb3b79405792636f3ca93458bd>:0 
  at System.Reflection.RuntimeReflectionExtensions.GetRuntimeProperties (System.Type type) [0x00006] in <2ffe54eb3b79405792636f3ca93458bd>:0 
  at System.Composition.TypedParts.Discovery.TypeInspector+<DiscoverPropertyExports>d__17.MoveNext () [0x0002f] in <c091afde214c4b8e8efbbeb9d44062d4>:0 
  at System.Composition.TypedParts.Discovery.TypeInspector+<DiscoverExports>d__0.MoveNext () [0x000eb] in <c091afde214c4b8e8efbbeb9d44062d4>:0 
  at System.Composition.TypedParts.Discovery.TypeInspector.InspectTypeForPart (System.Reflection.TypeInfo type, System.Composition.TypedParts.Discovery.DiscoveredPart& part) [0x00061] in <c091afde214c4b8e8efbbeb9d44062d4>:0 
  at System.Composition.TypedParts.TypedPartExportDescriptorProvider..ctor (System.Collections.Generic.IEnumerable`1[T] types, System.Composition.Convention.AttributedModelProvider attributeContext) [0x00039] in <c091afde214c4b8e8efbbeb9d44062d4>:0 
  at System.Composition.Hosting.ContainerConfiguration.CreateContainer () [0x00042] in <c091afde214c4b8e8efbbeb9d44062d4>:0 
  at Microsoft.CodeAnalysis.Host.Mef.MefHostServices.Create (System.Collections.Generic.IEnumerable`1[T] assemblies) [0x0001e] in <7f0d4b9d7a9a40cfa302b8c61f11defa>:0 
  at Microsoft.CodeAnalysis.Host.Mef.DesktopMefHostServices.get_DefaultServices () [0x00011] in <43494904657a4fb99e35e930a2c70ef9>:0 
  at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create (System.Collections.Generic.IDictionary`2[TKey,TValue] properties) [0x00000] in <43494904657a4fb99e35e930a2c70ef9>:0 
  at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create () [0x00000] in <43494904657a4fb99e35e930a2c70ef9>:0 
  at TestRoslyn.MainClass.Main (System.String[] args) [0x00001] in <7bd0678d90084049afa493941d8c6c7b>:0 
...

So just it seems like Microsoft.CodeAnalysis.Workspaces.Desktop isn't likely to be usable from Mono (AFAIK we don't have a Microsoft.VisualStudio.RemoteControl for VSMac)

mhutch commented 7 years ago

cc @KirillOsenkov

KirillOsenkov commented 7 years ago

cc @Therzok @CyrusNajmabadi @heejaechang this rings a bell, haven't we seen this recently? RemoteControl?

Therzok commented 7 years ago

I have not. I did not get anything in the remote workspace chain into our usage of Workspaces.Desktop. This either is a new dependency or it was skipped during our catalog construction.

Therzok commented 7 years ago

Ah, yes, it's a pure MSBuildWorkspace dependency. We do not instantiate that

DustinCampbell commented 7 years ago

It looks like a layering violation was introduced awhile back with https://github.com/dotnet/roslyn/pull/14055 when a reference to Microsoft.VisualStudio.RemoteControl to Microsoft.CodeAnalysis.Workspaces.Desktop. This was removed with https://github.com/dotnet/roslyn/commit/b104fbf4dd6d0fe86942029f2044b43ef2db62af.

Note: @Pilchie, this dependency was moved to the editor layer, but I'm not sure that's the right place yet. If Microsoft.VisualStudio.RemoteControl is a VS dependency, it should be factored into the VS layer.

heejaechang commented 7 years ago

can we move MSBuildWorkspace out from Workspace.Desktop? it being there require anyone who just want Workspace.Desktop to have dependency to MSBuild.

DustinCampbell commented 7 years ago

@heejaechang: I don't think that's the problem here.

heejaechang commented 7 years ago

@DustinCampbell yep, I know. just saying so that if we are going to do something with layering, might fix all layering issue together :)

DustinCampbell commented 7 years ago

Well, originally, this project was created for MSBuildWorkspace. Since it's a public API, moving it would be a breaking change.