When using XAML compilation, StackOverflowException is raised in XamlCTask if the conditions are just right
#2,550 opened on Apr 26, 2018
Repository metrics
- Stars
- (5,644 stars)
- PR merge metrics
- (No merged PRs in 30d)
Description
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:
- All binaries must be built to the same directory
- The netstandard.dll forwarding assembly must already be in the output folder (this comes from a .net framework project referencing a .net standard dll)
- 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)
- 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:
- 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.
- 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.
- 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.
- 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
- Download reproduction
- Open a VS 2017 developer command prompt
- 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
- Version with issue: 3.0-pre4