Skip to content

[ProjectCracker] stackoverflow exception with Build Tools 2017 #714

@ghost

Description

Project cracker crashes with stackoverflow exception when Microsoft Build Tools 2013 is installed, but Microsoft Build Tools 2015 is not.

Repro steps

  1. Ensure Microsoft Build Tools 2013 is installed, and Microsoft Build Tools 2015 is not.
  2. Ionide is installed with VsCode, Visual Studio is not installed.
  3. Run FSharp.Compiler.Service.ProjectCrackerTool.exe --test abc true from %USERPROFILE%\.vscode\extensions\Ionide.Ionide-fsharp-2.23.5\bin where abc can be anything
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions