xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

When using XAML compilation, StackOverflowException is raised in XamlCTask if the conditions are just right #2550

Open ptsoccer opened 6 years ago

ptsoccer commented 6 years ago

Description

In a particular certain set of circumstances, the XamlCTask will error in a stack overflow in which the mono cecil library ping pongs between mscorlib and netstandard looking for System.Type.

The steps are pretty convoluted, my attached file is setup the way it needs to be. The environment needed for the exception to occur is:

  1. All binaries must be built to the same directory
  2. The netstandard.dll forwarding assembly must already be in the output folder (this comes from a .net framework project referencing a .net standard dll)
  3. The xamarin forms project must reference a project that is first on the primary reference list for the xamarin forms project (usually accomplished by giving the reference a name that starts with a,b,c or something)
  4. XAML compilation must be turned on in a view (need this for XamlCTask to resolve references and emite il).

With this setup, when XamlCTask executes it:

  1. Splits the ReferencePath and adds each directory to the search path. Because the referenced project starts with a,b,c the first directory on the search path is the output folder.
  2. Because XAML compilation is turned on, TryCoreCompile imports System.Type from mscorlib. XamlCAssemblyResolver finds this dll in the netstandard.library nuget package. This is a forwarding assembly that forwards to netstandard.dll.
  3. Mono cecil then attempts to resolve System.Type in netstandard.dll. Because the netstandard.dll is already in the output folder and the output folder is first in the search directories, XamlCAssemblyResolver resolves netstandard.dll to the one in the output folder. This is a problem, however, because that dll is a forwarding assembly that forwards to mscorlib.dll.
  4. Mono cecil now tries to resolve System.Type in mscorlib.dll, and thus the stack overflow happens.

For this to not have happened, netstandard.dll should have been loaded from the netstandard.library nuget package. I believe this can be done by preferring to load the requested dlls in the ReferencePath property first, and if it doesn't find it there, look in the search directories in the XamlCAssemblyResolver class.

Steps to Reproduce

  1. Download reproduction
  2. Open a VS 2017 developer command prompt
  3. Run the following msbuild command, be sure to specify the path to the solution file, and also be sure to specify the path to the solution directory for the OutputPath:

MSBuild.exe "<Path to XamarinStaticBinding.sln>" /p:OutputPath="<Path to solution folder>\Output" /restore /p:Configuration="Release" /p:Platform="Any CPU" /verbosity:minimal

Expected Behavior

Compile succeeds

Actual Behavior

MSBuild crashes with a StackOverflowException

Basic Information

Reproduction Link

XamarinStaticBinding.zip

samhouts commented 4 years ago

This issue doesn't seem to have had any activity in a long time. We're working on prioritizing issues and resolving them as quickly as we can. To help us get through the list, we would appreciate an update from you to let us know if this is still affecting you on the latest version of Xamarin.Forms, since it's possible that we may have resolved this as part of another related or duplicate issue. If we don't see any new activity on this issue in the next 30 days, we'll evaluate whether this issue should be closed. Thank you!

ptsoccer commented 4 years ago

I just tried with version 4.8.0.1269 and it's still an issue

PureWeen commented 4 years ago

@StephaneDelcroix FYI