-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement SourceLink for Windows PDBs #18539
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection.Metadata; | ||
using System.Reflection.PortableExecutable; | ||
using System.Text; | ||
using Microsoft.CodeAnalysis.CSharp.Test.Utilities; | ||
using Microsoft.CodeAnalysis.Debugging; | ||
using Microsoft.CodeAnalysis.Emit; | ||
using Microsoft.CodeAnalysis.Test.Utilities; | ||
using Roslyn.Test.Utilities; | ||
using Xunit; | ||
|
||
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.PDB | ||
{ | ||
public class PDBSourceLinkTests : CSharpPDBTestBase | ||
{ | ||
[Theory] | ||
[InlineData(DebugInformationFormat.Pdb)] | ||
[InlineData(DebugInformationFormat.PortablePdb)] | ||
public void SourceLink(DebugInformationFormat format) | ||
{ | ||
string source = @" | ||
using System; | ||
|
||
class C | ||
{ | ||
public static void Main() | ||
{ | ||
Console.WriteLine(); | ||
} | ||
} | ||
"; | ||
var sourceLinkBlob = Encoding.UTF8.GetBytes(@" | ||
{ | ||
""documents"": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: open brace on new line #WontFix There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not C# ;) #WontFix |
||
""f:/build/*"" : ""https://raw.githubusercontent.com/my-org/my-project/1111111111111111111111111111111111111111/*"" | ||
} | ||
} | ||
"); | ||
|
||
var c = CreateStandardCompilation(Parse(source, "f:/build/foo.cs"), options: TestOptions.DebugDll); | ||
|
||
var pdbStream = new MemoryStream(); | ||
c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(format), pdbStream: pdbStream, sourceLinkStream: new MemoryStream(sourceLinkBlob)); | ||
|
||
var actualData = PdbValidation.GetSourceLinkData(pdbStream); | ||
AssertEx.Equal(sourceLinkBlob, actualData); | ||
} | ||
|
||
[Fact] | ||
public void SourceLink_Embedded() | ||
{ | ||
string source = @" | ||
using System; | ||
|
||
class C | ||
{ | ||
public static void Main() | ||
{ | ||
Console.WriteLine(); | ||
} | ||
} | ||
"; | ||
var sourceLinkBlob = Encoding.UTF8.GetBytes(@" | ||
{ | ||
""documents"": { | ||
""f:/build/*"" : ""https://raw.githubusercontent.com/my-org/my-project/1111111111111111111111111111111111111111/*"" | ||
} | ||
} | ||
"); | ||
var c = CreateStandardCompilation(Parse(source, "f:/build/foo.cs"), options: TestOptions.DebugDll); | ||
|
||
var peBlob = c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.Embedded), sourceLinkStream: new MemoryStream(sourceLinkBlob)); | ||
|
||
using (var peReader = new PEReader(peBlob)) | ||
{ | ||
var embeddedEntry = peReader.ReadDebugDirectory().Single(e => e.Type == DebugDirectoryEntryType.EmbeddedPortablePdb); | ||
|
||
using (var embeddedMetadataProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(embeddedEntry)) | ||
{ | ||
var pdbReader = embeddedMetadataProvider.GetMetadataReader(); | ||
|
||
var actualBlob = | ||
(from cdiHandle in pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition) | ||
let cdi = pdbReader.GetCustomDebugInformation(cdiHandle) | ||
where pdbReader.GetGuid(cdi.Kind) == PortableCustomDebugInfoKinds.SourceLink | ||
select pdbReader.GetBlobBytes(cdi.Value)).Single(); | ||
|
||
AssertEx.Equal(sourceLinkBlob, actualBlob); | ||
} | ||
} | ||
} | ||
|
||
[Theory] | ||
[InlineData(DebugInformationFormat.Pdb)] | ||
[InlineData(DebugInformationFormat.Embedded)] | ||
[InlineData(DebugInformationFormat.PortablePdb)] | ||
public void SourceLink_Errors(DebugInformationFormat format) | ||
{ | ||
string source = @" | ||
using System; | ||
|
||
class C | ||
{ | ||
public static void Main() | ||
{ | ||
Console.WriteLine(); | ||
} | ||
} | ||
"; | ||
var sourceLinkStream = new TestStream(canRead: true, readFunc: (_, __, ___) => { throw new Exception("Error!"); }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hopefully, discards will be supported in lambdas soon ;-) #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
var c = CreateStandardCompilation(Parse(source, "f:/build/foo.cs"), options: TestOptions.DebugDll); | ||
var pdbStream = format != DebugInformationFormat.Embedded ? new MemoryStream() : null; | ||
var result = c.Emit(new MemoryStream(), pdbStream, options: EmitOptions.Default.WithDebugInformationFormat(format), sourceLinkStream: sourceLinkStream); | ||
result.Diagnostics.Verify( | ||
// error CS0041: Unexpected error writing debug information -- 'Error!' | ||
Diagnostic(ErrorCode.FTL_DebugEmitFailure).WithArguments("Error!").WithLocation(1, 1)); | ||
} | ||
|
||
[Theory] | ||
[InlineData(DebugInformationFormat.Pdb)] | ||
[InlineData(DebugInformationFormat.PortablePdb)] | ||
public void SourceLink_Empty(DebugInformationFormat format) | ||
{ | ||
string source = @" | ||
using System; | ||
|
||
class C | ||
{ | ||
public static void Main() | ||
{ | ||
Console.WriteLine(); | ||
} | ||
} | ||
"; | ||
var sourceLinkBlob = new byte[0]; | ||
|
||
var c = CreateStandardCompilation(Parse(source, "f:/build/foo.cs"), options: TestOptions.DebugDll); | ||
|
||
var pdbStream = new MemoryStream(); | ||
c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(format), pdbStream: pdbStream, sourceLinkStream: new MemoryStream(sourceLinkBlob)); | ||
pdbStream.Position = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this position reset necessary? Maybe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
var bs = Roslyn.Utilities.StreamExtensions.ReadAllBytes(pdbStream); | ||
var actualData = PdbValidation.GetSourceLinkData(pdbStream); | ||
AssertEx.Equal(sourceLinkBlob, actualData); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the VB command-line parser have a similar change? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, forgot about that.
In reply to: 113746766 [](ancestors = 113746766)