Пример #1
0
        /// <summary>
        /// Returns the portable PDB reader for the assembly path
        /// </summary>
        /// <param name="assemblyPath">file path of the assembly or null</param>
        /// <param name="loadedPeAddress">loaded PE image address or zero</param>
        /// <param name="loadedPeSize">loaded PE image size</param>
        /// <param name="inMemoryPdbAddress">in memory PDB address or zero</param>
        /// <param name="inMemoryPdbSize">in memory PDB size</param>
        /// <param name="reader">returns the reader</param>
        /// <returns>reader</returns>
        private MetadataReader GetReader(string assemblyPath, IntPtr loadedPeAddress, int loadedPeSize, IntPtr inMemoryPdbAddress, int inMemoryPdbSize)
        {
            if (loadedPeAddress != IntPtr.Zero)
            {
                Tuple <MetadataReaderProvider, MetadataReader> tuple;
                if (_readerCache.TryGetValue(loadedPeAddress, out tuple))
                {
                    return(tuple.Item2);
                }
            }

            MetadataReaderProvider provider = null;
            MetadataReader         reader   = null;

            if (assemblyPath != null)
            {
                uint stamp;
                int  age;
                Guid guid;

                string pdbName = GetPdbPathFromPeStream(assemblyPath, loadedPeAddress, loadedPeSize, out age, out guid, out stamp);
                if (pdbName != null && File.Exists(pdbName))
                {
                    Stream pdbStream = File.OpenRead(pdbName);

                    provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream);
                    MetadataReader rdr = provider.GetMetadataReader();

                    // Validate that the PDB matches the assembly version
                    if (age == 1 && IdEquals(rdr.DebugMetadataHeader.Id, guid, stamp))
                    {
                        reader = rdr;
                    }
                    else
                    {
                        provider.Dispose();
                        provider = null;
                    }
                }
            }
            else if (inMemoryPdbAddress != IntPtr.Zero && inMemoryPdbSize > 0)
            {
                unsafe
                {
                    provider = MetadataReaderProvider.FromPortablePdbImage((byte *)inMemoryPdbAddress.ToPointer(), inMemoryPdbSize);
                    reader   = provider.GetMetadataReader();
                }
            }

            if (reader != null && loadedPeAddress != IntPtr.Zero)
            {
                _readerCache.Add(loadedPeAddress, Tuple.Create(provider, reader));
            }

            return(reader);
        }
Пример #2
0
        /// <summary>
        /// Reads the data pointed to by the specified Debug Directory entry and interprets them as Embedded Portable PDB blob.
        /// </summary>
        /// <returns>
        /// Provider of a metadata reader reading Portable PDB image.
        /// </returns>
        /// <exception cref="ArgumentException"><paramref name="entry"/> is not a <see cref="DebugDirectoryEntryType.EmbeddedPortablePdb"/> entry.</exception>
        /// <exception cref="BadImageFormatException">Bad format of the data.</exception>
        public unsafe MetadataReaderProvider ReadEmbeddedPortablePdbDebugDirectoryData(DebugDirectoryEntry entry)
        {
            if (entry.Type != DebugDirectoryEntryType.EmbeddedPortablePdb)
            {
                throw new ArgumentException(SR.NotCodeViewEntry, nameof(entry));
            }

            ValidateEmbeddedPortablePdbVersion(entry);

            using (var block = GetDebugDirectoryEntryDataBlock(entry))
            {
                var pdbImage = DecodeEmbeddedPortablePdbDebugDirectoryData(block);
                return(MetadataReaderProvider.FromPortablePdbImage(pdbImage));
            }
        }
        /// <summary>
        /// Reads the data pointed to by the specified Debug Directory entry and interprets them as Embedded Portable PDB blob.
        /// </summary>
        /// <returns>
        /// Provider of a metadata reader reading Portable PDB image.
        /// </returns>
        /// <exception cref="ArgumentException"><paramref name="entry"/> is not a <see cref="DebugDirectoryEntryType.EmbeddedPortablePdb"/> entry.</exception>
        /// <exception cref="BadImageFormatException">Bad format of the data.</exception>
        /// <exception cref="InvalidOperationException">PE image not available.</exception>
        public MetadataReaderProvider ReadEmbeddedPortablePdbDebugDirectoryData(DebugDirectoryEntry entry)
        {
            if (entry.Type != DebugDirectoryEntryType.EmbeddedPortablePdb)
            {
                Throw.InvalidArgument(SR.Format(SR.UnexpectedDebugDirectoryType, nameof(DebugDirectoryEntryType.EmbeddedPortablePdb)), nameof(entry));
            }

            ValidateEmbeddedPortablePdbVersion(entry);

            using (var block = GetDebugDirectoryEntryDataBlock(entry))
            {
                var pdbImage = DecodeEmbeddedPortablePdbDebugDirectoryData(block);
                return(MetadataReaderProvider.FromPortablePdbImage(pdbImage));
            }
        }
Пример #4
0
        private static MetadataReaderProvider GetMetadataReaderProvider(Module module)
        {
            // TODO can the PEReader be pointed at a memory location instead of reading from disk?
            var dllFileContent = File.ReadAllBytes(module.FullyQualifiedName).ToImmutableArray();
            var reader         = new PEReader(dllFileContent);

            TraceSourceLink("probing for embedded symbols: " + module.FullyQualifiedName);
            if (!reader.HasMetadata)
            {
                return(null);
            }

            // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/tests/PortableExecutable/PEReaderTests.cs
            var embeddedPdb = reader.ReadDebugDirectory().FirstOrDefault(x => x.Type == DebugDirectoryEntryType.EmbeddedPortablePdb);

            if (!embeddedPdb.Equals(default(DebugDirectoryEntry)))
            {
                TraceSourceLink("found embedded symbols: " + module.FullyQualifiedName);
                return(reader.ReadEmbeddedPortablePdbDebugDirectoryData(embeddedPdb));
            }

            var sbFile = new StringBuilder(1024);
            var sbPath = new StringBuilder(1024);

            if (SymGetSymbolFile(ProcessHandle, null, module.FullyQualifiedName, SymbolFileType.sfPdb, sbFile, sbFile.Capacity, sbPath, sbPath.Capacity))
            {
                // todo determine if pdb is not portable early
                // https://github.com/tmat/corefx/blob/f808e59c3ef93e141b019d661a4443a0e19c7442/src/System.Diagnostics.StackTrace/src/System/Diagnostics/StackTraceSymbols.CoreCLR.cs#L164
                TraceSourceLink("probing for portable PDB symbols: " + sbFile);
                var pdbFileContent = File.ReadAllBytes(sbFile.ToString()).ToImmutableArray();
                return(MetadataReaderProvider.FromPortablePdbImage(pdbFileContent));
            }
            else
            {
                TraceSourceLink("probing for portable PDB symbols failed: " + Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()));
            }

            return(null);
        }
Пример #5
0
        public void MethodExtents(DebugInformationFormat format)
        {
            var source0 = MarkedSource(@"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""1111111111111111111111111111111111111111""
using System;

public class C
{
    int A() => 1;                  
                                   
    void F()                       
    {                              
#line 10 ""C:\F\A.cs""               
        Console.WriteLine();
#line 20 ""C:\F\B.cs""
        Console.WriteLine();
#line default
    }

    int E() => 1;

    void G()
    {
        Func<int> H1 = <N:0>() => 1</N:0>;

        Action H2 = <N:1>() =>
        {
            Func<int> H3 = <N:2>() => 3</N:2>;

        }</N:1>;
    }
}                              
", fileName: @"C:\Enc1.cs");

            var source1 = MarkedSource(@"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""2222222222222222222222222222222222222222""
using System;

public class C
{
    int A() => 1;                 
                              
    void F()                      
    {                             
#line 10 ""C:\F\A.cs""         
        Console.WriteLine();
#line 10 ""C:\F\C.cs""
        Console.WriteLine();
#line default
    }

    void G()
    {
        Func<int> H1 = <N:0>() => 1</N:0>;

        Action H2 = <N:1>() =>
        {
            Func<int> H3 = <N:2>() => 3</N:2>;
            Func<int> H4 = <N:3>() => 4</N:3>;
        }</N:1>;
    }

    int E() => 1;
}
", fileName: @"C:\Enc1.cs");

            var source2 = MarkedSource(@"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""3333333333333333333333333333333333333333""
using System;

public class C
{
    int A() => 3;                 
                              
    void F()       
    {    
#line 10 ""C:\F\B.cs""
        Console.WriteLine();
#line 10 ""C:\F\E.cs""
        Console.WriteLine();
#line default
    }

    void G()
    {
        

        Action H2 = <N:1>() =>
        {
            
            Func<int> H4 = <N:3>() => 4</N:3>;
        }</N:1>;
    }

    int E() => 1;  

    int B() => 4;
}
", fileName: @"C:\Enc1.cs");

            var compilation0 = CreateCompilationWithMscorlib(source0.Tree, options: ComSafeDebugDll.WithMetadataImportOptions(MetadataImportOptions.All), assemblyName: "EncMethodExtents");
            var compilation1 = compilation0.WithSource(source1.Tree);
            var compilation2 = compilation1.WithSource(source2.Tree);

            compilation0.VerifyDiagnostics();
            compilation1.VerifyDiagnostics();
            compilation2.VerifyDiagnostics();

            var v0  = CompileAndVerify(compilation0, emitOptions: EmitOptions.Default.WithDebugInformationFormat(format));
            var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData);

            var f0 = compilation0.GetMember <MethodSymbol>("C.F");
            var f1 = compilation1.GetMember <MethodSymbol>("C.F");
            var f2 = compilation2.GetMember <MethodSymbol>("C.F");

            var g0 = compilation0.GetMember <MethodSymbol>("C.G");
            var g1 = compilation1.GetMember <MethodSymbol>("C.G");
            var g2 = compilation2.GetMember <MethodSymbol>("C.G");

            var a1 = compilation1.GetMember <MethodSymbol>("C.A");
            var a2 = compilation2.GetMember <MethodSymbol>("C.A");

            var b2 = compilation2.GetMember <MethodSymbol>("C.B");

            var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo);

            var syntaxMap1 = GetSyntaxMapFromMarkers(source0, source1);
            var diff1      = compilation1.EmitDifference(
                generation0,
                ImmutableArray.Create(
                    new SemanticEdit(SemanticEditKind.Update, f0, f1, syntaxMap1, preserveLocalVariables: true),
                    new SemanticEdit(SemanticEditKind.Update, g0, g1, syntaxMap1, preserveLocalVariables: true)));

            diff1.VerifySynthesizedMembers(
                "C: {<>c}",
                "C.<>c: {<>9__3_0, <>9__3_2, <>9__3_3#1, <>9__3_1, <G>b__3_0, <G>b__3_1, <G>b__3_2, <G>b__3_3#1}");

            var reader1 = diff1.GetMetadata().Reader;

            CheckEncLogDefinitions(reader1,
                                   Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
                                   Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
                                   Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField),
                                   Row(5, TableIndex.Field, EditAndContinueOperation.Default),
                                   Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
                                   Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
                                   Row(8, TableIndex.MethodDef, EditAndContinueOperation.Default),
                                   Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default),
                                   Row(10, TableIndex.MethodDef, EditAndContinueOperation.Default),
                                   Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddMethod),
                                   Row(11, TableIndex.MethodDef, EditAndContinueOperation.Default));

            if (format == DebugInformationFormat.PortablePdb)
            {
                using (var pdbProvider = MetadataReaderProvider.FromPortablePdbImage(diff1.PdbDelta))
                {
                    CheckEncMap(pdbProvider.GetMetadataReader(),
                                Handle(2, TableIndex.MethodDebugInformation),
                                Handle(4, TableIndex.MethodDebugInformation),
                                Handle(8, TableIndex.MethodDebugInformation),
                                Handle(9, TableIndex.MethodDebugInformation),
                                Handle(10, TableIndex.MethodDebugInformation),
                                Handle(11, TableIndex.MethodDebugInformation));
                }
            }

            diff1.VerifyPdb(Enumerable.Range(0x06000001, 20), @"
<symbols>
  <files>
    <file id=""1"" name=""C:\Enc1.cs"" language=""3f5162f8-07c6-11d3-9053-00c04fa302a1"" languageVendor=""994b45c4-e6e9-11d2-903f-00c04fa302a1"" documentType=""5a869d0b-6611-11d3-bd2a-0000f80849bd"" checkSumAlgorithmId=""ff1816ec-aa5e-4d10-87f7-6f4963833460"" checkSum=""D1, 84, C6,  3, AA, 83, C0, CF, 49, E2, 52, 48, BB, 35, 99, 51, 88, 2B, 6C, D6, "" />
    <file id=""2"" name=""C:\F\A.cs"" language=""3f5162f8-07c6-11d3-9053-00c04fa302a1"" languageVendor=""994b45c4-e6e9-11d2-903f-00c04fa302a1"" documentType=""5a869d0b-6611-11d3-bd2a-0000f80849bd"" />
    <file id=""3"" name=""C:\F\C.cs"" language=""3f5162f8-07c6-11d3-9053-00c04fa302a1"" languageVendor=""994b45c4-e6e9-11d2-903f-00c04fa302a1"" documentType=""5a869d0b-6611-11d3-bd2a-0000f80849bd"" />
  </files>
  <methods>
    <method token=""0x6000002"">
      <customDebugInfo>
        <using>
          <namespace usingCount=""1"" />
        </using>
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""9"" startColumn=""5"" endLine=""9"" endColumn=""6"" document=""1"" />
        <entry offset=""0x1"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""2"" />
        <entry offset=""0x7"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""3"" />
        <entry offset=""0xd"" startLine=""15"" startColumn=""5"" endLine=""15"" endColumn=""6"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0xe"">
        <namespace name=""System"" />
      </scope>
    </method>
    <method token=""0x6000004"">
      <customDebugInfo>
        <forward token=""0x6000002"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""18"" startColumn=""5"" endLine=""18"" endColumn=""6"" document=""1"" />
        <entry offset=""0x1"" startLine=""19"" startColumn=""9"" endLine=""19"" endColumn=""43"" document=""1"" />
        <entry offset=""0x21"" startLine=""21"" startColumn=""9"" endLine=""25"" endColumn=""17"" document=""1"" />
        <entry offset=""0x41"" startLine=""26"" startColumn=""5"" endLine=""26"" endColumn=""6"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x42"">
        <local name=""H1"" il_index=""2"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" />
        <local name=""H2"" il_index=""3"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" />
      </scope>
    </method>
    <method token=""0x6000008"">
      <customDebugInfo>
        <forward token=""0x6000002"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""19"" startColumn=""35"" endLine=""19"" endColumn=""36"" document=""1"" />
      </sequencePoints>
    </method>
    <method token=""0x6000009"">
      <customDebugInfo>
        <forward token=""0x6000002"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""22"" startColumn=""9"" endLine=""22"" endColumn=""10"" document=""1"" />
        <entry offset=""0x1"" startLine=""23"" startColumn=""13"" endLine=""23"" endColumn=""47"" document=""1"" />
        <entry offset=""0x21"" startLine=""24"" startColumn=""13"" endLine=""24"" endColumn=""47"" document=""1"" />
        <entry offset=""0x41"" startLine=""25"" startColumn=""9"" endLine=""25"" endColumn=""10"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x42"">
        <local name=""H3"" il_index=""1"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" />
        <local name=""H4"" il_index=""2"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" />
      </scope>
    </method>
    <method token=""0x600000a"">
      <customDebugInfo>
        <forward token=""0x6000002"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""23"" startColumn=""39"" endLine=""23"" endColumn=""40"" document=""1"" />
      </sequencePoints>
    </method>
    <method token=""0x600000b"">
      <customDebugInfo>
        <forward token=""0x6000002"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""24"" startColumn=""39"" endLine=""24"" endColumn=""40"" document=""1"" />
      </sequencePoints>
    </method>
  </methods>
</symbols>
");
            var syntaxMap2 = GetSyntaxMapFromMarkers(source1, source2);
            var diff2      = compilation2.EmitDifference(
                diff1.NextGeneration,
                ImmutableArray.Create(
                    new SemanticEdit(SemanticEditKind.Update, f1, f2, syntaxMap2, preserveLocalVariables: true),
                    new SemanticEdit(SemanticEditKind.Update, g1, g2, syntaxMap2, preserveLocalVariables: true),
                    new SemanticEdit(SemanticEditKind.Update, a1, a2, syntaxMap2, preserveLocalVariables: true),
                    new SemanticEdit(SemanticEditKind.Insert, null, b2)));

            diff2.VerifySynthesizedMembers(
                "C: {<>c}",
                "C.<>c: {<>9__3_3#1, <>9__3_1, <G>b__3_1, <G>b__3_3#1, <>9__3_0, <>9__3_2, <G>b__3_0, <G>b__3_2}");

            var reader2 = diff2.GetMetadata().Reader;

            CheckEncLogDefinitions(reader2,
                                   Row(5, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
                                   Row(6, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
                                   Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default),
                                   Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
                                   Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
                                   Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default),
                                   Row(11, TableIndex.MethodDef, EditAndContinueOperation.Default),
                                   Row(2, TableIndex.TypeDef, EditAndContinueOperation.AddMethod),
                                   Row(12, TableIndex.MethodDef, EditAndContinueOperation.Default));

            if (format == DebugInformationFormat.PortablePdb)
            {
                using (var pdbProvider = MetadataReaderProvider.FromPortablePdbImage(diff2.PdbDelta))
                {
                    CheckEncMap(pdbProvider.GetMetadataReader(),
                                Handle(1, TableIndex.MethodDebugInformation),
                                Handle(2, TableIndex.MethodDebugInformation),
                                Handle(4, TableIndex.MethodDebugInformation),
                                Handle(9, TableIndex.MethodDebugInformation),
                                Handle(11, TableIndex.MethodDebugInformation),
                                Handle(12, TableIndex.MethodDebugInformation));
                }
            }

            diff2.VerifyPdb(Enumerable.Range(0x06000001, 20), @"
<symbols>
  <files>
    <file id=""1"" name=""C:\Enc1.cs"" language=""3f5162f8-07c6-11d3-9053-00c04fa302a1"" languageVendor=""994b45c4-e6e9-11d2-903f-00c04fa302a1"" documentType=""5a869d0b-6611-11d3-bd2a-0000f80849bd"" checkSumAlgorithmId=""ff1816ec-aa5e-4d10-87f7-6f4963833460"" checkSum=""4D, 14, 76, DE, 68, ED, ED, C1, 88, DF,  C, 85, 1C, 6B, 15, F7, BE, C0, 34, 34, "" />
    <file id=""2"" name=""C:\F\B.cs"" language=""3f5162f8-07c6-11d3-9053-00c04fa302a1"" languageVendor=""994b45c4-e6e9-11d2-903f-00c04fa302a1"" documentType=""5a869d0b-6611-11d3-bd2a-0000f80849bd"" />
    <file id=""3"" name=""C:\F\E.cs"" language=""3f5162f8-07c6-11d3-9053-00c04fa302a1"" languageVendor=""994b45c4-e6e9-11d2-903f-00c04fa302a1"" documentType=""5a869d0b-6611-11d3-bd2a-0000f80849bd"" />
  </files>
  <methods>
    <method token=""0x6000001"">
      <customDebugInfo>
        <using>
          <namespace usingCount=""1"" />
        </using>
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""6"" startColumn=""16"" endLine=""6"" endColumn=""17"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x2"">
        <namespace name=""System"" />
      </scope>
    </method>
    <method token=""0x6000002"">
      <customDebugInfo>
        <forward token=""0x6000001"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""9"" startColumn=""5"" endLine=""9"" endColumn=""6"" document=""1"" />
        <entry offset=""0x1"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""2"" />
        <entry offset=""0x7"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""3"" />
        <entry offset=""0xd"" startLine=""15"" startColumn=""5"" endLine=""15"" endColumn=""6"" document=""1"" />
      </sequencePoints>
    </method>
    <method token=""0x6000004"">
      <customDebugInfo>
        <forward token=""0x6000001"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""18"" startColumn=""5"" endLine=""18"" endColumn=""6"" document=""1"" />
        <entry offset=""0x1"" startLine=""21"" startColumn=""9"" endLine=""25"" endColumn=""17"" document=""1"" />
        <entry offset=""0x22"" startLine=""26"" startColumn=""5"" endLine=""26"" endColumn=""6"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x23"">
        <local name=""H2"" il_index=""4"" il_start=""0x0"" il_end=""0x23"" attributes=""0"" />
      </scope>
    </method>
    <method token=""0x6000009"">
      <customDebugInfo>
        <forward token=""0x6000001"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""22"" startColumn=""9"" endLine=""22"" endColumn=""10"" document=""1"" />
        <entry offset=""0x1"" startLine=""24"" startColumn=""13"" endLine=""24"" endColumn=""47"" document=""1"" />
        <entry offset=""0x21"" startLine=""25"" startColumn=""9"" endLine=""25"" endColumn=""10"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x22"">
        <local name=""H4"" il_index=""1"" il_start=""0x0"" il_end=""0x22"" attributes=""0"" />
      </scope>
    </method>
    <method token=""0x600000b"">
      <customDebugInfo>
        <forward token=""0x6000001"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""24"" startColumn=""39"" endLine=""24"" endColumn=""40"" document=""1"" />
      </sequencePoints>
    </method>
    <method token=""0x600000c"">
      <customDebugInfo>
        <forward token=""0x6000001"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""30"" startColumn=""16"" endLine=""30"" endColumn=""17"" document=""1"" />
      </sequencePoints>
    </method>
  </methods>
</symbols>
");
        }
Пример #6
0
        internal static MetadataReaderProvider CreateProviderFromStream(IStream stream)
        {
            var interopStream = new ReadOnlyInteropStream(stream);
            var header        = new byte[2 * sizeof(int)];
            int bytesRead     = interopStream.TryReadAll(header, 0, header.Length);

            MetadataReaderProvider provider;

            // detect Embedded Portable PDB signature:
            if (bytesRead == header.Length && header[0] == 'M' && header[1] == 'P' && header[2] == 'D' && header[3] == 'B')
            {
                int size = BitConverter.ToInt32(header, startIndex: sizeof(int));

                // TODO: https://github.com/dotnet/symreader-portable/issues/47
                // We could avoid allocating managed memory here if FromPortablePdbImage accepted non-seekable stream in prefetch mode.
                // The implementation in S.R.M. allocates native memory.
                byte[] decompressed;
                try
                {
                    decompressed = new byte[size];
                }
                catch
                {
                    throw new BadImageFormatException();
                }

                var deflate = new DeflateStream(interopStream, CompressionMode.Decompress, leaveOpen: true);
                if (size > 0)
                {
                    int actualLength;

                    try
                    {
                        actualLength = deflate.TryReadAll(decompressed, 0, decompressed.Length);
                    }
                    catch (InvalidDataException e)
                    {
                        throw new BadImageFormatException(e.Message, e.InnerException);
                    }

                    if (actualLength != decompressed.Length)
                    {
                        throw new BadImageFormatException();
                    }
                }

                // Check that there is no more compressed data left,
                // in case the decompressed size specified in the header is smaller
                // than the actual decompressed size of the data.
                if (deflate.ReadByte() != -1)
                {
                    throw new BadImageFormatException();
                }

                provider = MetadataReaderProvider.FromPortablePdbImage(ImmutableByteArrayInterop.DangerousCreateFromUnderlyingArray(ref decompressed));
            }
            else
            {
                interopStream.Position = 0;
                provider = MetadataReaderProvider.FromPortablePdbStream(interopStream);
            }

            return(provider);
        }
Пример #7
0
        public void MethodExtents(DebugInformationFormat format)
        {
            var source0 = MarkedSource(
                WithWindowsLineBreaks(
                    @"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""1111111111111111111111111111111111111111""
using System;

public class C
{
    int A() => 1;                  
                                   
    void F()                       
    {                              
#line 10 ""C:\F\A.cs""               
        Console.WriteLine();
#line 20 ""C:\F\B.cs""
        Console.WriteLine();
#line default
    }

    int E() => 1;

    void G()
    {
        Func<int> <N:4>H1</N:4> = <N:0>() => 1</N:0>;

        Action <N:5>H2</N:5> = <N:1>() =>
        {
            Func<int> <N:6>H3</N:6> = <N:2>() => 3</N:2>;

        }</N:1>;
    }
}                              
"
                    ),
                fileName: @"C:\Enc1.cs"
                );

            var source1 = MarkedSource(
                WithWindowsLineBreaks(
                    @"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""2222222222222222222222222222222222222222""
using System;

public class C
{
    int A() => 1;                 
                              
    void F()                      
    {                             
#line 10 ""C:\F\A.cs""         
        Console.WriteLine();
#line 10 ""C:\F\C.cs""
        Console.WriteLine();
#line default
    }

    void G()
    {
        Func<int> <N:4>H1</N:4> = <N:0>() => 1</N:0>;

        Action <N:5>H2</N:5> = <N:1>() =>
        {
            Func<int> <N:6>H3</N:6> = <N:2>() => 3</N:2>;
            Func<int> <N:7>H4</N:7> = <N:3>() => 4</N:3>;
        }</N:1>;
    }

    int E() => 1;
}
"
                    ),
                fileName: @"C:\Enc1.cs"
                );

            var source2 = MarkedSource(
                WithWindowsLineBreaks(
                    @"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""3333333333333333333333333333333333333333""
using System;

public class C
{
    int A() => 3;                 
                              
    void F()       
    {    
#line 10 ""C:\F\B.cs""
        Console.WriteLine();
#line 10 ""C:\F\E.cs""
        Console.WriteLine();
#line default
    }

    void G()
    {
        

        Action <N:5>H2</N:5> = <N:1>() =>
        {
            
            Func<int> <N:7>H4</N:7> = <N:3>() => 4</N:3>;
        }</N:1>;
    }

    int E() => 1;  

    int B() => 4;
}
"
                    ),
                fileName: @"C:\Enc1.cs"
                );

            var compilation0 = CreateCompilation(
                source0.Tree,
                options: ComSafeDebugDll.WithMetadataImportOptions(MetadataImportOptions.All),
                assemblyName: "EncMethodExtents"
                );
            var compilation1 = compilation0.WithSource(source1.Tree);
            var compilation2 = compilation1.WithSource(source2.Tree);

            compilation0.VerifyDiagnostics();
            compilation1.VerifyDiagnostics();
            compilation2.VerifyDiagnostics();

            var v0 = CompileAndVerify(
                compilation0,
                emitOptions: EmitOptions.Default.WithDebugInformationFormat(format)
                );
            var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData);

            var f0 = compilation0.GetMember <MethodSymbol>("C.F");
            var f1 = compilation1.GetMember <MethodSymbol>("C.F");
            var f2 = compilation2.GetMember <MethodSymbol>("C.F");

            var g0 = compilation0.GetMember <MethodSymbol>("C.G");
            var g1 = compilation1.GetMember <MethodSymbol>("C.G");
            var g2 = compilation2.GetMember <MethodSymbol>("C.G");

            var a1 = compilation1.GetMember <MethodSymbol>("C.A");
            var a2 = compilation2.GetMember <MethodSymbol>("C.A");

            var b2 = compilation2.GetMember <MethodSymbol>("C.B");

            var generation0 = EmitBaseline.CreateInitialBaseline(
                md0,
                v0.CreateSymReader().GetEncMethodDebugInfo
                );

            var syntaxMap1 = GetSyntaxMapFromMarkers(source0, source1);
            var diff1      = compilation1.EmitDifference(
                generation0,
                ImmutableArray.Create(
                    SemanticEdit.Create(
                        SemanticEditKind.Update,
                        f0,
                        f1,
                        syntaxMap1,
                        preserveLocalVariables: true
                        ),
                    SemanticEdit.Create(
                        SemanticEditKind.Update,
                        g0,
                        g1,
                        syntaxMap1,
                        preserveLocalVariables: true
                        )
                    )
                );

            diff1.VerifySynthesizedMembers(
                "C: {<>c}",
                "C.<>c: {<>9__3_0, <>9__3_2, <>9__3_3#1, <>9__3_1, <G>b__3_0, <G>b__3_1, <G>b__3_2, <G>b__3_3#1}"
                );

            var reader1 = diff1.GetMetadata().Reader;

            CheckEncLogDefinitions(
                reader1,
                Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
                Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
                Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField),
                Row(5, TableIndex.Field, EditAndContinueOperation.Default),
                Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
                Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
                Row(8, TableIndex.MethodDef, EditAndContinueOperation.Default),
                Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default),
                Row(10, TableIndex.MethodDef, EditAndContinueOperation.Default),
                Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddMethod),
                Row(11, TableIndex.MethodDef, EditAndContinueOperation.Default)
                );

            if (format == DebugInformationFormat.PortablePdb)
            {
                using var pdbProvider = MetadataReaderProvider.FromPortablePdbImage(diff1.PdbDelta);

                CheckEncMap(
                    pdbProvider.GetMetadataReader(),
                    Handle(2, TableIndex.MethodDebugInformation),
                    Handle(4, TableIndex.MethodDebugInformation),
                    Handle(8, TableIndex.MethodDebugInformation),
                    Handle(9, TableIndex.MethodDebugInformation),
                    Handle(10, TableIndex.MethodDebugInformation),
                    Handle(11, TableIndex.MethodDebugInformation)
                    );
            }

            diff1.VerifyPdb(
                Enumerable.Range(0x06000001, 20),
                @"
<symbols>
  <files>
    <file id=""1"" name=""C:\Enc1.cs"" language=""C#"" checksumAlgorithm=""SHA1"" checksum=""0B-95-CB-78-00-AE-C7-34-45-D9-FB-31-E4-30-A4-0E-FC-EA-9E-95"" />
    <file id=""2"" name=""C:\F\A.cs"" language=""C#"" />
    <file id=""3"" name=""C:\F\C.cs"" language=""C#"" />
  </files>
  <methods>
    <method token=""0x6000002"">
      <customDebugInfo>
        <using>
          <namespace usingCount=""1"" />
        </using>
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""9"" startColumn=""5"" endLine=""9"" endColumn=""6"" document=""1"" />
        <entry offset=""0x1"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""2"" />
        <entry offset=""0x7"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""3"" />
        <entry offset=""0xd"" startLine=""15"" startColumn=""5"" endLine=""15"" endColumn=""6"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0xe"">
        <namespace name=""System"" />
      </scope>
    </method>
    <method token=""0x6000004"">
      <customDebugInfo>
        <forward token=""0x6000002"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""18"" startColumn=""5"" endLine=""18"" endColumn=""6"" document=""1"" />
        <entry offset=""0x1"" startLine=""19"" startColumn=""9"" endLine=""19"" endColumn=""54"" document=""1"" />
        <entry offset=""0x21"" startLine=""21"" startColumn=""9"" endLine=""25"" endColumn=""17"" document=""1"" />
        <entry offset=""0x41"" startLine=""26"" startColumn=""5"" endLine=""26"" endColumn=""6"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x42"">
        <local name=""H1"" il_index=""0"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" />
        <local name=""H2"" il_index=""1"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" />
      </scope>
    </method>
    <method token=""0x6000008"">
      <customDebugInfo>
        <forward token=""0x6000002"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""19"" startColumn=""46"" endLine=""19"" endColumn=""47"" document=""1"" />
      </sequencePoints>
    </method>
    <method token=""0x6000009"">
      <customDebugInfo>
        <forward token=""0x6000002"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""22"" startColumn=""9"" endLine=""22"" endColumn=""10"" document=""1"" />
        <entry offset=""0x1"" startLine=""23"" startColumn=""13"" endLine=""23"" endColumn=""58"" document=""1"" />
        <entry offset=""0x21"" startLine=""24"" startColumn=""13"" endLine=""24"" endColumn=""58"" document=""1"" />
        <entry offset=""0x41"" startLine=""25"" startColumn=""9"" endLine=""25"" endColumn=""10"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x42"">
        <local name=""H3"" il_index=""0"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" />
        <local name=""H4"" il_index=""1"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" />
      </scope>
    </method>
    <method token=""0x600000a"">
      <customDebugInfo>
        <forward token=""0x6000002"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""23"" startColumn=""50"" endLine=""23"" endColumn=""51"" document=""1"" />
      </sequencePoints>
    </method>
    <method token=""0x600000b"">
      <customDebugInfo>
        <forward token=""0x6000002"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""24"" startColumn=""50"" endLine=""24"" endColumn=""51"" document=""1"" />
      </sequencePoints>
    </method>
  </methods>
</symbols>
"
                );
            var syntaxMap2 = GetSyntaxMapFromMarkers(source1, source2);
            var diff2      = compilation2.EmitDifference(
                diff1.NextGeneration,
                ImmutableArray.Create(
                    SemanticEdit.Create(
                        SemanticEditKind.Update,
                        f1,
                        f2,
                        syntaxMap2,
                        preserveLocalVariables: true
                        ),
                    SemanticEdit.Create(
                        SemanticEditKind.Update,
                        g1,
                        g2,
                        syntaxMap2,
                        preserveLocalVariables: true
                        ),
                    SemanticEdit.Create(
                        SemanticEditKind.Update,
                        a1,
                        a2,
                        syntaxMap2,
                        preserveLocalVariables: true
                        ),
                    SemanticEdit.Create(SemanticEditKind.Insert, null, b2)
                    )
                );

            diff2.VerifySynthesizedMembers(
                "C: {<>c}",
                "C.<>c: {<>9__3_3#1, <>9__3_1, <G>b__3_1, <G>b__3_3#1, <>9__3_0, <>9__3_2, <G>b__3_0, <G>b__3_2}"
                );

            var reader2 = diff2.GetMetadata().Reader;

            CheckEncLogDefinitions(
                reader2,
                Row(5, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
                Row(6, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
                Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default),
                Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
                Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
                Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default),
                Row(11, TableIndex.MethodDef, EditAndContinueOperation.Default),
                Row(2, TableIndex.TypeDef, EditAndContinueOperation.AddMethod),
                Row(12, TableIndex.MethodDef, EditAndContinueOperation.Default)
                );

            if (format == DebugInformationFormat.PortablePdb)
            {
                using var pdbProvider = MetadataReaderProvider.FromPortablePdbImage(diff2.PdbDelta);

                CheckEncMap(
                    pdbProvider.GetMetadataReader(),
                    Handle(1, TableIndex.MethodDebugInformation),
                    Handle(2, TableIndex.MethodDebugInformation),
                    Handle(4, TableIndex.MethodDebugInformation),
                    Handle(9, TableIndex.MethodDebugInformation),
                    Handle(11, TableIndex.MethodDebugInformation),
                    Handle(12, TableIndex.MethodDebugInformation)
                    );
            }

            diff2.VerifyPdb(
                Enumerable.Range(0x06000001, 20),
                @"
<symbols>
  <files>
    <file id=""1"" name=""C:\Enc1.cs"" language=""C#"" checksumAlgorithm=""SHA1"" checksum=""9C-B9-FF-18-0E-9F-A4-22-93-85-A8-5A-06-11-43-1E-64-3E-88-06"" />
    <file id=""2"" name=""C:\F\B.cs"" language=""C#"" />
    <file id=""3"" name=""C:\F\E.cs"" language=""C#"" />
  </files>
  <methods>
    <method token=""0x6000001"">
      <customDebugInfo>
        <using>
          <namespace usingCount=""1"" />
        </using>
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""6"" startColumn=""16"" endLine=""6"" endColumn=""17"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x2"">
        <namespace name=""System"" />
      </scope>
    </method>
    <method token=""0x6000002"">
      <customDebugInfo>
        <forward token=""0x6000001"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""9"" startColumn=""5"" endLine=""9"" endColumn=""6"" document=""1"" />
        <entry offset=""0x1"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""2"" />
        <entry offset=""0x7"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""3"" />
        <entry offset=""0xd"" startLine=""15"" startColumn=""5"" endLine=""15"" endColumn=""6"" document=""1"" />
      </sequencePoints>
    </method>
    <method token=""0x6000004"">
      <customDebugInfo>
        <forward token=""0x6000001"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""18"" startColumn=""5"" endLine=""18"" endColumn=""6"" document=""1"" />
        <entry offset=""0x1"" startLine=""21"" startColumn=""9"" endLine=""25"" endColumn=""17"" document=""1"" />
        <entry offset=""0x21"" startLine=""26"" startColumn=""5"" endLine=""26"" endColumn=""6"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x22"">
        <local name=""H2"" il_index=""1"" il_start=""0x0"" il_end=""0x22"" attributes=""0"" />
      </scope>
    </method>
    <method token=""0x6000009"">
      <customDebugInfo>
        <forward token=""0x6000001"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""22"" startColumn=""9"" endLine=""22"" endColumn=""10"" document=""1"" />
        <entry offset=""0x1"" startLine=""24"" startColumn=""13"" endLine=""24"" endColumn=""58"" document=""1"" />
        <entry offset=""0x21"" startLine=""25"" startColumn=""9"" endLine=""25"" endColumn=""10"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x22"">
        <local name=""H4"" il_index=""1"" il_start=""0x0"" il_end=""0x22"" attributes=""0"" />
      </scope>
    </method>
    <method token=""0x600000b"">
      <customDebugInfo>
        <forward token=""0x6000001"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""24"" startColumn=""50"" endLine=""24"" endColumn=""51"" document=""1"" />
      </sequencePoints>
    </method>
    <method token=""0x600000c"">
      <customDebugInfo>
        <forward token=""0x6000001"" />
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""30"" startColumn=""16"" endLine=""30"" endColumn=""17"" document=""1"" />
      </sequencePoints>
    </method>
  </methods>
</symbols>
"
                );
        }