Skip to content

Conversation

@vzarytovskii
Copy link
Member

Summary

This fixes import scope tables in the portabl PDB files for F#.

Currently, for the following code:

namespace A

open System

module Foo =
    let getcwd () = Environment.CurrentDirectory

F# compiler will not emit additional import scope tables (i.e. only "empty" default one) :

<?xml version="1.0" encoding="utf-8"?>
<Pdb Name="a" Path="a.pdb" AssemblyPath="a.exe" PdbType="Portable" Signature="6c81791a-07b4-4a2c-a6b7-59f570bbddbc" TimeDateStamp="89B9D968" AgeOrTimestampFromAssembly="BB6DD17D " SignatureFromAssembly="888fa5fb-3fd3-417a-9a77-e07ae9f49c36 " PdbFileFromAssembly="a.pdb ">
  <UserEntryPoint>null</UserEntryPoint>
  <Document Index="1" DocumentType="Text" Language="F#" LanguageVendor="Microsoft" ChecksumAlgorithm="SHA-256" Checksum="cc 56 ad 33 75 8e 98 b1 aa 79 38 e6 eb c4 16 1c 1f d5 20 d5 8e 66 4d 9d 41 b6 04 3e 3c 93 4b 9c ">a.fs</Document>
  <ImportScope Index="1" Parent="null" />
  <Method Token="6000001" LocalVariablesSignatureToken="11000000">
    <SequencePoints DocumentIndex="1">
      <SequencePoint IlOffset="IL_0000" StartLine="6" StartColumn="21" EndLine="6" EndColumn="49" />
    </SequencePoints>
    <Scope OffsetRange="IL_0000-IL_0006" IsRoot="True" Method="6000001" />
  </Method>
</Pdb>

The current behaviour in the expression evaluator (before the change):
ppdb-fsharp-before

For comparison, the following C# code:

namespace A;

using System;

class Foo {
    static string GetCwd() => Environment.CurrentDirectory;
}

will emit the following portable PDB:

<?xml version="1.0" encoding="utf-8"?>
<Pdb Name="csharp" Path="bin\Debug\net6.0\csharp.pdb" AssemblyPath="bin\Debug\net6.0\csharp.dll" PdbType="Portable" Signature="4241ca48-3ec2-460e-8bc1-f10243796775" TimeDateStamp="C65A2FBC" AgeOrTimestampFromAssembly="C65A2FBC 0 " SignatureFromAssembly="4241ca48-3ec2-460e-8bc1-f10243796775 00000000-0000-0000-0000-000000000000 " PdbFileFromAssembly="obj\Debug\net6.0\csharp.pdb - ">
  <UserEntryPoint>null</UserEntryPoint>
  <Document Index="1" DocumentType="Text" Language="C#" LanguageVendor="Microsoft" ChecksumAlgorithm="SHA-256" Checksum="65 75 67 ba 8f aa 3e 0c ce 9c d8 4d 8c ed 67 b3 5c 45 1b 15 03 69 65 95 a0 fa bf 74 fb b2 3a 16 ">Program.cs</Document>
  <Document Index="2" DocumentType="Text" Language="C#" LanguageVendor="Microsoft" ChecksumAlgorithm="SHA-256" Checksum="f3 f1 34 e9 e8 25 e3 e7 26 80 90 f5 8b 1a f2 bd a2 de 51 3f 61 a0 9c 56 f4 8b 9b 8d 08 61 2a bc ">obj\Debug\net6.0\csharp.GlobalUsings.g.cs</Document>
  <Document Index="3" DocumentType="Text" Language="C#" LanguageVendor="Microsoft" ChecksumAlgorithm="SHA-256" Checksum="92 03 cf 07 d3 6b 1a a1 35 da 4a 5f 86 28 6f 34 43 21 56 cb af 65 18 c2 90 98 49 eb 7d 57 73 81 ">obj\Debug\net6.0\.NETCoreApp,Version=v6.0.AssemblyAttributes.cs</Document>
  <Document Index="4" DocumentType="Text" Language="C#" LanguageVendor="Microsoft" ChecksumAlgorithm="SHA-256" Checksum="11 f5 f9 9e 89 4d 9c ec 1f f3 57 7b 6f 62 ed 3f 20 70 d1 bc 88 9c 9f 07 8b f9 19 12 2b 63 63 e4 ">obj\Debug\net6.0\csharp.AssemblyInfo.cs</Document>
  <ImportScope Index="1" Parent="null" />
  <ImportScope Index="2" Parent="1">
    <Import>System</Import>
    <Import>System.Collections.Generic</Import>
    <Import>System.IO</Import>
    <Import>System.Linq</Import>
    <Import>System.Net.Http</Import>
    <Import>System.Threading</Import>
    <Import>System.Threading.Tasks</Import>
  </ImportScope>
  <ImportScope Index="3" Parent="2">
    <Import>System</Import>
  </ImportScope>
  <Method Token="6000005" LocalVariablesSignatureToken="11000000">
    <SequencePoints DocumentIndex="1">
      <SequencePoint IlOffset="IL_0000" StartLine="6" StartColumn="31" EndLine="6" EndColumn="59" />
    </SequencePoints>
    <Scope OffsetRange="IL_0000-IL_0006" IsRoot="True" Method="6000005" ImportScope="3" />
  </Method>
</Pdb>

Behaviour when debugging C# project:
ppdb-csharp

This PR adds emitting of import scope tables: we will always flatten imports and emit only one table (same as C# compiler does).

Emitted PDB after change:

<?xml version="1.0" encoding="utf-8"?>
<Pdb Name="a" Path="a.pdb" AssemblyPath="a.exe" PdbType="Portable" Signature="8985c22e-c2f9-4477-8765-3541e5f97e9c" TimeDateStamp="AD13CD04" AgeOrTimestampFromAssembly="AD13CD04 " SignatureFromAssembly="8985c22e-c2f9-4477-8765-3541e5f97e9c " PdbFileFromAssembly="a.pdb ">
  <UserEntryPoint>6000001</UserEntryPoint>
  <Document Index="1" DocumentType="Text" Language="F#" LanguageVendor="Microsoft" ChecksumAlgorithm="SHA-256" Checksum="cf 01 00 39 b3 84 b5 a8 2c 70 9e fd 04 18 46 82 f4 de a5 f1 65 84 ea 0b b7 74 20 fa 1e ef cd 1c ">a.fs</Document>
  <ImportScope Index="1" Parent="null" />
  <ImportScope Index="2" Parent="1">
    <Import>Microsoft</Import>
    <Import>Microsoft.FSharp</Import>
    <Import>Microsoft.FSharp.Core</Import>
    <Import>Microsoft.FSharp.Collections</Import>
    <Import>Microsoft.FSharp.Control</Import>
    <Import>System</Import>
  </ImportScope>
  <Method Token="6000001" LocalVariablesSignatureToken="11000000">
    <SequencePoints DocumentIndex="1">
      <SequencePoint IlOffset="IL_0000" StartLine="8" StartColumn="5" EndLine="8" EndColumn="17" />
      <SequencePoint IlOffset="IL_0010" StartLine="9" StartColumn="5" EndLine="9" EndColumn="6" />
    </SequencePoints>
    <Scope OffsetRange="IL_0000-IL_0012" IsRoot="True" Method="6000001" ImportScope="2" />
  </Method>
  <Method Token="6000002" LocalVariablesSignatureToken="11000000">
    <SequencePoints DocumentIndex="1">
      <SequencePoint IlOffset="IL_0000" StartLine="4" StartColumn="21" EndLine="4" EndColumn="49" />
    </SequencePoints>
    <Scope OffsetRange="IL_0000-IL_0006" IsRoot="True" Method="6000002" ImportScope="2" />
  </Method>
</Pdb>

Behaviour after the change:

ppdb-fsharp-after

@vzarytovskii vzarytovskii marked this pull request as draft March 9, 2022 14:35
@vzarytovskii
Copy link
Member Author

Will add some pdb dumper + baseline tests.

@vzarytovskii vzarytovskii added the Area-Debug stepping, debug points, stacks and more label Mar 10, 2022
@vzarytovskii vzarytovskii self-assigned this Mar 10, 2022
@vzarytovskii vzarytovskii added this to the Backlog milestone Mar 10, 2022
@vzarytovskii vzarytovskii linked an issue Mar 10, 2022 that may be closed by this pull request
@vzarytovskii vzarytovskii added Feature Improvement Theme-Simple-F# A cross-community initiative called "Simple F#", keeping people in the sweet spot of the language. labels Mar 10, 2022
@vzarytovskii
Copy link
Member Author

Huh, some curious fsi tests failures...

[xUnit.net 00:00:20.17]     FSharp.Compiler.UnitTests.FsiTests.Seven bound values are ordered and have their correct name [FAIL]
  Failed FSharp.Compiler.UnitTests.FsiTests.Able to find a bound value by the identifier and has valid info [237 ms]
  Error Message:
   FSharp.Compiler.Interactive.Shell+FsiCompilationException : Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing
  Stack Trace:
     at FSharp.Compiler.Interactive.Shell.FsiEvaluationSession.commitResult[a,b](FSharpChoice`2 res) in /home/vsts/work/1/s/src/fsharp/fsi/fsi.fs:line 3322
   at FSharp.Compiler.Interactive.Shell.FsiEvaluationSession.EvalInteraction(String code, FSharpOption`1 cancellationToken) in /home/vsts/work/1/s/src/fsharp/fsi/fsi.fs:line 3472
   at FSharp.Compiler.UnitTests.FsiTests.Able to find a bound value by the identifier and has valid info() in /home/vsts/work/1/s/tests/FSharp.Compiler.UnitTests/FsiTests.fs:line 131
  Failed FSharp.Compiler.UnitTests.FsiTests.Seven bound values are ordered and have their correct name [237 ms]
  Error Message:
   FSharp.Compiler.Interactive.Shell+FsiCompilationException : Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing
  Stack Trace:
     at FSharp.Compiler.Interactive.Shell.FsiEvaluationSession.commitResult[a,b](FSharpChoice`2 res) in /home/vsts/work/1/s/src/fsharp/fsi/fsi.fs:line 3322
   at FSharp.Compiler.Interactive.Shell.FsiEvaluationSession.EvalInteraction(String code, FSharpOption`1 cancellationToken) in /home/vsts/work/1/s/src/fsharp/fsi/fsi.fs:line 3472
   at FSharp.Compiler.UnitTests.FsiTests.Seven bound values are ordered and have their correct name() in /home/vsts/work/1/s/tests/FSharp.Compiler.UnitTests/FsiTests.fs:line 67

Copy link
Contributor

@dsyme dsyme left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great

@vzarytovskii vzarytovskii marked this pull request as ready for review March 21, 2022 17:31
Copy link
Contributor

@KevinRansom KevinRansom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comments, otherwise looks good.

@vzarytovskii vzarytovskii enabled auto-merge (squash) March 25, 2022 11:13
@vzarytovskii vzarytovskii merged commit eb59dc5 into dotnet:main Mar 28, 2022
@dsyme
Copy link
Contributor

dsyme commented Mar 28, 2022

So good to have this fixed at last!

charlesroddie pushed a commit to charlesroddie/fsharp that referenced this pull request May 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Debug stepping, debug points, stacks and more Feature Improvement Theme-Simple-F# A cross-community initiative called "Simple F#", keeping people in the sweet spot of the language.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit open namespaces, modules, types to debug data

3 participants