Skip to content

Rebuild assemblies with non-embedded PDBs#52272

Merged
RikkiGibson merged 36 commits intodotnet:mainfrom
RikkiGibson:rebuild-pdb
Apr 6, 2021
Merged

Rebuild assemblies with non-embedded PDBs#52272
RikkiGibson merged 36 commits intodotnet:mainfrom
RikkiGibson:rebuild-pdb

Conversation

@RikkiGibson
Copy link
Copy Markdown
Member

@RikkiGibson RikkiGibson commented Mar 31, 2021

Closes #51890

Tagging @jaredpar. I have the implementation side working fine, but there's an issue with CompilationDiff that I can't track down. See #52272 (comment) Resolved.

jaredpar and others added 23 commits March 28, 2021 12:42
This adds a file system abstraction sufficient to hook all file open
events inside `CommonCompiler`. This is necessary to fully test the
rebuild scenarios that we need to add
The determinism / round trip tests in emit were depending on a bug in
our test framework. The metadata writer only emits references if there
is a name associated with the reference. Before my PR all of our in
memory references lacked image names and hence they were omitted from
the PDB. Once I fixed that they started showing up and needed to be
accounted for in the logic.
Co-authored-by: Youssef Victor <youssefvictor00@gmail.com>
@ghost ghost added the Area-Compilers label Mar 31, 2021
@RikkiGibson RikkiGibson marked this pull request as ready for review April 1, 2021 01:27
@RikkiGibson RikkiGibson requested review from a team as code owners April 1, 2021 01:27

return list;

IEnumerable<CommandInfo> Permutate(CommandInfo commandInfo)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IEnumerable [](start = 12, length = 11)

Consider declaring these local functions (other than Add) as static?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done

if (rebuildPdbStream is null)
{
rebuildPdbReader = rebuildReader.GetEmbeddedPdbMetadataReader() ?? throw new InvalidOperationException();
rebuildPdbBytes = new ReadOnlySpan<byte>(rebuildPdbReader.MetadataPointer, rebuildPdbReader.MetadataLength).ToArray().ToImmutableArray();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ToArray() [](start = 124, length = 9)

Minor: Is ToArray() needed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Unfortunately, I haven't been able to find API on ReadOnlySpan which allows creating an ImmutableArray without copying (save for creating a builder and copying the items over manually, I guess, which we could do)

https://stackoverflow.com/questions/66912187/how-should-i-create-an-immutablearray-from-a-span-readonlyspan?noredirect=1#comment118278058_66912187

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Punting on this since it's test code.

Assert.NotNull(originalPdbReader);

var pdbSpan = new ReadOnlySpan<byte>(originalPdbReader!.MetadataPointer, originalPdbReader.MetadataLength);
return new EmitInfo(originalBytes, originalReader, pdbSpan.ToArray().ToImmutableArray(), originalPdbReader);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ToArray() [](start = 87, length = 9)

Is ToArray() needed?

Assert.Equal(originalBytes.ToArray(), rebuildStream.ToArray());

var rebuildBytes = rebuildStream.ToImmutable();
var rebuildReader = new PEReader(rebuildBytes);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

var rebuildReader [](start = 12, length = 17)

Should we use using var ... = new PEReader(bytes); here and in cases below?

try
// Find the embedded pdb
var originalBinaryStream = File.OpenRead(assemblyInfo.FilePath);
var originalPeReader = new PEReader(originalBinaryStream);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why remove the using from these two declarations?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I believe I removed this because I was tracking down #52272 (comment). At first I was concerned about reintroducing this because it looks like the PEReader can escape the method via CompilationDiff, but now I see that there is no field of type PEReader on CompilationDiff, so I think we're in the clear with that.

It feels like we might want to make a pass over data types which contain disposable things to determine if the containing type should be made disposable, and to check if things are actually getting disposed when they need to.

Comment on lines +193 to +194


Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change

Nit: double blank line

var originalMdv = getMdv(originalEmit.PdbReader);
var rebuildMdv = getMdv(rebuildEmit.PdbReader);

Assert.True(false, $@"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we should be passing this to the xUnit output infrastructure. That is usually presented with full information where as Assert failures will often clip information and make it hard to read.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I will punt this to #52327 if that's ok. I agree that the whole output should probably go through the test output helper. But it might make sense to put the diff in the assert failure message.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That's fine


// https://github.com/dotnet/roslyn/issues/52327
// this is not all that useful without manual copy/pasting. Can we diff this during the test and show the differences?
Assert.True(false, $@"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we should be passing this to the xUnit output infrastructure. That is usually presented with full information where as Assert failures will often clip information and make it hard to read.

{
MetadataReaderProvider? pdbReaderProvider = null;
// Find the embedded pdb
using var originalPeReader = new PEReader(File.OpenRead(assemblyInfo.FilePath));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

File.OpenRead(assemblyInfo.FilePath) [](start = 54, length = 36)

Does PEReader.Dispose() dispose of the Stream?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

https://docs.microsoft.com/en-us/dotnet/api/system.reflection.portableexecutable.pereader.-ctor?view=net-5.0#System_Reflection_PortableExecutable_PEReader__ctor_System_IO_Stream_

Ownership of the stream is transferred to the PEReader upon successful validation of constructor arguments. It will be disposed by the PEReader and the caller must not manipulate it.

@RikkiGibson RikkiGibson enabled auto-merge (squash) April 6, 2021 23:03
@RikkiGibson RikkiGibson merged commit 1431a93 into dotnet:main Apr 6, 2021
@ghost ghost added this to the Next milestone Apr 6, 2021
@RikkiGibson RikkiGibson deleted the rebuild-pdb branch April 6, 2021 23:30
@dibarbet dibarbet modified the milestones: Next, 16.10.P3 Apr 26, 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.

Make Rebuild work with non-embedded PDBs

4 participants