Skip to content
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

Order PDB document table to match compiler arguments #50615

Merged
merged 8 commits into from Jan 25, 2021

Conversation

RikkiGibson
Copy link
Contributor

@RikkiGibson RikkiGibson commented Jan 19, 2021

PTAL @tmat @jaredpar

@ryzngard are there tests for the compilation options embedded in the PDBs? or would it be practical to add any?

Have filed #50611 to follow up on fixing the document order in native PDBs.

@@ -847,6 +847,7 @@ private void EmbedCompilationOptions(CommonPEModuleBuilder module)
WriteValue(CompilationOptionNames.CompilerVersion, compilerVersion);

WriteValue(CompilationOptionNames.Language, module.CommonCompilation.Options.Language);
WriteValue(CompilationOptionNames.SourceFileCount, module.CommonCompilation.SyntaxTrees.Count().ToString());
Copy link
Member

Choose a reason for hiding this comment

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

Count() [](start = 100, length = 7)

Minor thing and not related to your change but just noticed that SyntaxTrees is IEnumerable but both C# and VB represent it as ImmutableArray. So we are boxing it unnecessarily. Can't change public API but could change and use CommonSyntaxTrees.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that's a good idea. Let's spin it off into its own issue.

@RikkiGibson
Copy link
Contributor Author

RikkiGibson commented Jan 19, 2021

Does this PR need to target 16.9?

edit: It looks like master currently targets 16.9-preview4, so we can keep this base branch.

Copy link
Member

@tmat tmat left a comment

Choose a reason for hiding this comment

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

:shipit:

@ryzngard
Copy link
Contributor

are there tests for the compilation options embedded in the PDBs? or would it be practical to add any?

https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Test/Emit/PDB/CSharpDeterministicBuildCompilationTests.cs

This could probably use an update to the name of the tests too fwiw.

@RikkiGibson
Copy link
Contributor Author

Adding the "version" field was very straightforward so I decided to just do it in this PR.

}
}


Copy link
Member

Choose a reason for hiding this comment

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

Double blink line

Suggested change

// Ensure document table lists files in command line order
var documentsBuilder = Module.DebugDocumentsBuilder;
var documents = documentsBuilder.DebugDocuments;
foreach (var tree in Module.CommonCompilation.SyntaxTrees)
Copy link
Member

Choose a reason for hiding this comment

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

At this point in the code does this include SyntaxTree that come from source generators?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great question. I think the answer is yes because this is emit-phase work which we are only expected to do for the "final" compilation which includes source generator outputs.

It feels like it would be appropriate to have a test here.

Copy link
Member

Choose a reason for hiding this comment

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

Definitely need a test - it should also cover that all source generated files are embedded in the PDB.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not yet certain how to formulate this test. See this simple source generators test:

[Fact]
public void Single_File_Is_Added()
{
var source = @"
class C { }
";
var generatorSource = @"
class GeneratedClass { }
";
var parseOptions = TestOptions.Regular;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);
compilation.VerifyDiagnostics();
Assert.Single(compilation.SyntaxTrees);
SingleFileTestGenerator testGenerator = new SingleFileTestGenerator(generatorSource);
GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { testGenerator }, parseOptions: parseOptions);
driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out _);
Assert.Equal(2, outputCompilation.SyntaxTrees.Count());
Assert.NotEqual(compilation, outputCompilation);
var generatedClass = outputCompilation.GlobalNamespace.GetTypeMembers("GeneratedClass").Single();
Assert.True(generatedClass.Locations.Single().IsInSource);
}

If I try to imitate the structure of the source generator tests, I will create an original compilation, feed it into the generator driver, then get a final compilation out and try to emit with it. But it seems obvious that the syntax trees for that compilation will include the generated sources, so the test won't really be demonstrating anything useful.

It feels like if we had a higher level test that straight up ran through CommonCompiler.Run we might be able to demonstrate something meaningful, but I'm not sure it's good to spend the time to come up with the automated test just yet.

I also imagine that in the near future we might write a test harness that allows us to just take any Compilation and attempt to "round-trip" it, by emitting its dll+pdb, gathering the information to recreate it, and then doing so on the spot. Test failure messages could be given by comparing output of ildasm or mdv or something like that on the before and after binaries.

Copy link
Member

Choose a reason for hiding this comment

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

The test could verify that the PDB contains the sources of the generated files. That is, the compilation that comes out of the driver is setup correctly.

@@ -835,6 +835,9 @@ private void EmbedSourceLink(Stream stream)
value: _debugMetadataOpt.GetOrAddBlob(bytes));
}

///<summary>The version of the compilation options schema to be written to the PDB.</summary>
public const int Version = 1;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
public const int Version = 1;
public const int CompilationOptionsSchemaVersion = 1;

<file id=""1"" name=""a\..\a.cs"" language=""C#"" checksumAlgorithm=""406ea660-64cf-4c82-b6f0-42d48172a799"" checksum=""AB-00-7F-1D-23-D5"" />
<file id=""2"" name=""C:\a\..\b.cs"" language=""C#"" checksumAlgorithm=""SHA1"" checksum=""36-39-3C-83-56-97-F2-F0-60-95-A4-A0-32-C6-32-C7-B2-4B-16-92"" />
<file id=""1"" name=""C:\a\..\b.cs"" language=""C#"" checksumAlgorithm=""SHA1"" checksum=""36-39-3C-83-56-97-F2-F0-60-95-A4-A0-32-C6-32-C7-B2-4B-16-92"" />
<file id=""2"" name=""a\..\a.cs"" language=""C#"" checksumAlgorithm=""406ea660-64cf-4c82-b6f0-42d48172a799"" checksum=""AB-00-7F-1D-23-D5"" />
Copy link
Member

Choose a reason for hiding this comment

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

Why is there no checksum algorithm here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems like the checksum algorithm is present on this line. Am I misunderstanding something?

Copy link
Member

Choose a reason for hiding this comment

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

ugg, the double quoting fooled me.

@jaredpar
Copy link
Member

@dotnet/roslyn-compiler can we get one more review here? Part of the fix here is for 16.9 important bugs

@@ -28,5 +29,6 @@ internal static class CompilationOptionNames
public const string Nullable = "nullable";
public const string Define = "define";
public const string Strict = "strict";
public const string SourceFileCount = "source-file-count";
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The purpose of this property is to let us order the "real" documents at the beginning of the table, then allow documents added for #line directives to come at positions after this count so that we can skip them when rebuilding.

VerifyCompilationOptions(compilationOptions, originalCompilation, emitOptions, compilationOptionsReader, langVersion);
if (debugDocumentsCount is not null)
{
Assert.Equal(debugDocumentsCount, pdbReader.Documents.Count);
Copy link
Member

@cston cston Jan 25, 2021

Choose a reason for hiding this comment

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

Assert.Equal(debugDocumentsCount, pdbReader.Documents.Count); [](start = 24, length = 61)

Should we assert unconditionally? Assert.Equal(debugDocumentsCount ?? syntaxTrees.Length, pdbReader.Documents.Count);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could if we ensure every test that doesn't pass 'debugDocumentsCount' passes a unique path of each of its documents, which isn't hard to do.

foreach (var tree in Module.CommonCompilation.SyntaxTrees)
{
string normalizedPath = documentsBuilder.NormalizeDebugDocumentPath(tree.FilePath, basePath: null);
if (documents.TryGetValue(normalizedPath, out var doc) && !_documentIndex.ContainsKey(doc))
Copy link
Member

Choose a reason for hiding this comment

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

if (documents.TryGetDebugDocument(tree.FilePath, basePath: null) is { } doc && ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@RikkiGibson RikkiGibson merged commit ab05661 into dotnet:master Jan 25, 2021
@RikkiGibson RikkiGibson deleted the pdb-document-order branch January 25, 2021 21:11
@ghost ghost added this to the Next milestone Jan 25, 2021
@Cosifne Cosifne modified the milestones: Next, 16.9 Jan 27, 2021
@JoeRobich JoeRobich removed this from the 16.9 milestone Jan 27, 2021
@JoeRobich JoeRobich added this to the 16.9.P4 milestone Jan 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants