Skip to content

F# Compiler and Interactive both copy FSharp.Core to %TEMP% #2476

@allykzam

Description

@allykzam

One of my more "creative" (mischievous?) type providers calls fsc in order to build user-provided code, then performs reflection on the completed assembly. A test script I wrote for it makes use of the type provider, and runs in F# Interactive. After updating to F# 4.1 and FSharp.Core 4.1.0, both the instance of F# Interactive running the test code and the instance of fsc called by the type provider attempt to stash a copy of FSharp.Core.dll in %TEMP%, and fsc fails because that path is locked.

Repro steps

Provide the steps required to reproduce the problem

  1. Clone my TypeExpansion type provider and git checkout 1.0.0, then clone the sample templates
  2. Build the TypeExpansion type provider; the 1.0.0 release updated the type provider to use FSharp.Core version 4.1.0, and to use fsc from the new F# 4.1 locations
  3. In the templates project, open tests/FromXml/test.fsx and modify the first two lines to point to the locally-built libraries; for me, this means changing them to the following:
#r @"M:\Users\amazingant\GitHub\Amazingant.FSharp.TypeExpansion\Source\Amazingant.FSharp.TypeExpansion\bin\Debug\Amazingant.FSharp.TypeExpansion.Attributes.dll"
#r @"M:\Users\amazingant\GitHub\Amazingant.FSharp.TypeExpansion\Source\Amazingant.FSharp.TypeExpansion\bin\Debug\Amazingant.FSharp.TypeExpansion.dll"
  1. From the root of the templates project, run ./build.cmd RunTests to run the simple test suite; this test suite uses the FAKE.FSIHelper.executeFSI function to call F# Interactive and run the test.fsx script
  2. While the tests run, use Process Monitor with a filter on Path is C:\Users\<your-user-account>\AppData\Local\Temp\FSharp.Core.dll

Expected behavior

While running the tests, the compiler and/or F# Interactive should put any temporary files they think they need into a temporary file path, rather than assuming that %TEMP%/FSharp.Core.dll is available. This could come from System.IO.Path.GetTempFileName() for example.

Actual behavior

Both the compiler and F# Interactive try to lock %TEMP%/FSharp.Core.dll, and whichever process attempted to lock the file later returns an error.

Known workarounds

  • Use the F# 4.0 version of fsc:

    1. Revert commit f66fee7b968e50710cf4296337a985a5d702f0de in the TypeExpansion code
    2. Rebuild the type provider
    3. Re-run the test code
    4. Via procmon, observe that F# Interactive uses %TEMP%/FSharp.Core.dll, but fsc does not
  • Do not reference FSharp.Core version 4.1.0 from the type provider:

    1. Revert commit ea25117afdb976c3e98b84cc01d1759a79e9b9f7 in the TypeExpansion code
    2. Rebuild the type provider
    3. Re-run the test code
    4. Via procmon, observe that both F# Interactive and fsc use %TEMP%/FSharp.Core.dll, but neither of them prevent the other from accessing the file
  • Put FSharp.Core version 4.1.0 into the GAC manually with gacutil

    1. Find FSharp.Core.dll
    2. Run gacutil /i <path-to-dll> in an administrative command prompt
    3. Follow the main repro steps again
    4. Via procmon, observe that F# Interactive no longer puts a copy of FSharp.Core.dll into %TEMP%; fsc still does

My initial assumption was that the new version of FSharp.Core should exist in the GAC after Visual Studio is installed, but after reading some issue comments, it sounds like this may not be the case?

An additional commit in the type provider, commit de731a59fae8b8cb21c11b099678cec8b728fe96, can be reverted as well; this commit changes which version of FSharp.Core is used during the calls to fsc, but appears to have no effect on the results of these tests.

Related information

Provide any related information

  • Operating system: Win 10 Pro v1607
  • Branch: Installed with latest Visual Studio 2017 RC, Visual F# Tools version is 15.4.1.17020301

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions