-
Notifications
You must be signed in to change notification settings - Fork 123
Description
Project cracker crashes with stackoverflow exception when Microsoft Build Tools 2013 is installed, but Microsoft Build Tools 2015 is not.
Repro steps
- Ensure Microsoft Build Tools 2013 is installed, and Microsoft Build Tools 2015 is not.
- Ionide is installed with VsCode, Visual Studio is not installed.
- Run
FSharp.Compiler.Service.ProjectCrackerTool.exe --test abc truefrom%USERPROFILE%\.vscode\extensions\Ionide.Ionide-fsharp-2.23.5\binwhereabccan be anything - Observe crash (Process is terminated due to StackOverflowException)
Expected behavior
The application should not crash. If build tools 2015 is required, the user should be informed.
Actual behavior
The application crashes with stackoverflow.
Workaround
Ensure MSBuild tools 2015 is installed! From (here
Crash Analysis
Looking at the debug info, we see the following:
010f8068 72a3ea96 [GCFrame: 010f8068]
010fa878 72a3ea96 [HelperMethodFrame_PROTECTOBJ: 010fa878] System.Reflection.RuntimeAssembly._nLoad(System.Reflection.AssemblyName, System.String, System.Security.Policy.Evidence, System.Reflection.RuntimeAssembly, System.Threading.StackCrawlMark ByRef, IntPtr, Boolean, Boolean, Boolean)
010fa95c 625ceae5 System.Reflection.RuntimeAssembly.nLoad(System.Reflection.AssemblyName, System.String, System.Security.Policy.Evidence, System.Reflection.RuntimeAssembly, System.Threading.StackCrawlMark ByRef, IntPtr, Boolean, Boolean, Boolean)
010fa980 625c7039 System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(System.Reflection.AssemblyName, System.Security.Policy.Evidence, System.Reflection.RuntimeAssembly, System.Threading.StackCrawlMark ByRef, IntPtr, Boolean, Boolean, Boolean)
010fa9b8 625f3495 System.Reflection.Assembly.Load(System.Reflection.AssemblyName)
010fa9c4 031226fc Microsoft.FSharp.Compiler.SourceCodeServices.ProjectCrackerTool.ProjectCrackerTool+onResolveEvent@431.Invoke(System.Object, System.ResolveEventArgs) [C:\projects\fsharp-compiler-service\src\fsharp\FSharp.Compiler.Service.ProjectCrackerTool\ProjectCrackerTool.fs @ 441]
010fa9d8 625d1471 System.AppDomain.OnAssemblyResolveEvent(System.Reflection.RuntimeAssembly, System.String)
The crash appears to be an issue here where Assembly.Load is called in an infinite loop if the assembly is not resolved.
The first time the AppDomain.AssemblyResolve Event is fired, we see the code sets the desired build tools version to 12, indeed we can confirm this by inspecting the object (use !dumpstackobjects to get object address)
First, dump the AssemblyName object:
0:000> !DumpObj /d 02dc59d4
Name: System.Reflection.AssemblyName
MethodTable: 62719918
EEClass: 622df308
Size: 60(0x3c) bytes
File: C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
626ff7a4 4001ad0 4 System.String 0 instance 02dc5a84 _Name
62704448 4001ad1 8 System.Byte[] 0 instance 00000000 _PublicKey
62704448 4001ad2 c System.Byte[] 0 instance 02dc5ac4 _PublicKeyToken
6270348c 4001ad3 10 ...ation.CultureInfo 0 instance 02dc5a28 _CultureInfo
626ff7a4 4001ad4 14 System.String 0 instance 00000000 _CodeBase
627036fc 4001ad5 18 System.Version 0 instance 02dc5af0 _Version
6270f174 4001ad6 1c ...StrongNameKeyPair 0 instance 00000000 _StrongNameKeyPair
6271a368 4001ad7 20 ...SerializationInfo 0 instance 00000000 m_siInfo
62704448 4001ad8 24 System.Byte[] 0 instance 00000000 _HashForControl
6270f0c0 4001ad9 28 System.Int32 1 instance 0 _HashAlgorithm
6270f0c0 4001ada 2c System.Int32 1 instance 0 _HashAlgorithmForControl
6270f0f8 4001adb 30 System.Int32 1 instance 1 _VersionCompatibility
6270f130 4001adc 34 System.Int32 1 instance 0 _Flags
Next, we dump out the System.Version field that is set.
0:000> !DumpObj /d 02dc5af0
Name: System.Version
MethodTable: 627036fc
EEClass: 622d7460
Size: 24(0x18) bytes
File: C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
62701638 4000704 4 System.Int32 1 instance 12 _Major
62701638 4000705 8 System.Int32 1 instance 0 _Minor
62701638 4000706 c System.Int32 1 instance 0 _Build
62701638 4000707 10 System.Int32 1 instance 0 _Revision
627001ac 4000708 1b8 System.Char[] 0 shared static SeparatorsArray
>> Domain:Value 00f8cde0:02dc4d0c <<
We now know that everything is being set to search for version 12 of the build tools, which I definitely have installed (looking in C:\Program Files (x86)\MSBuild\12.0\Bin confirms this). We can test the presence further in FSI, which shows that we successfully load the build framework:
> let x = System.Reflection.AssemblyName("Microsoft.Build.Framework");;
val x : System.Reflection.AssemblyName = Microsoft.Build.Framework
> x.Version <- System.Version("12.0.0.0");;
val it : unit = ()
> System.Reflection.Assembly.Load(x);;
Binding session to 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Build.Framework.dll'...
val it : System.Reflection.Assembly =
Microsoft.Build.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
{CodeBase = "file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Microsoft.Build.Framework/v4.0_4.0.0.0__b03f5f7f11d50a3a/Microsoft.Build.Framework.dll";
CustomAttributes = seq...
What is unclear is why this build framework is not resolved via project cracker.
Related information
- Windows 10
- .NET 4.6.1
- VsCode
- Microsoft Build Tools 2013