Rebuild assemblies with non-embedded PDBs#52272
Conversation
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>
src/Compilers/Core/RebuildTest/Microsoft.CodeAnalysis.Rebuild.UnitTests.csproj
Show resolved
Hide resolved
|
|
||
| return list; | ||
|
|
||
| IEnumerable<CommandInfo> Permutate(CommandInfo commandInfo) |
There was a problem hiding this comment.
IEnumerable [](start = 12, length = 11)
Consider declaring these local functions (other than Add) as static?
| if (rebuildPdbStream is null) | ||
| { | ||
| rebuildPdbReader = rebuildReader.GetEmbeddedPdbMetadataReader() ?? throw new InvalidOperationException(); | ||
| rebuildPdbBytes = new ReadOnlySpan<byte>(rebuildPdbReader.MetadataPointer, rebuildPdbReader.MetadataLength).ToArray().ToImmutableArray(); |
There was a problem hiding this comment.
ToArray() [](start = 124, length = 9)
Minor: Is ToArray() needed?
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
ToArray() [](start = 87, length = 9)
Is ToArray() needed?
| Assert.Equal(originalBytes.ToArray(), rebuildStream.ToArray()); | ||
|
|
||
| var rebuildBytes = rebuildStream.ToImmutable(); | ||
| var rebuildReader = new PEReader(rebuildBytes); |
There was a problem hiding this comment.
var rebuildReader [](start = 12, length = 17)
Should we use using var ... = new PEReader(bytes); here and in cases below?
src/Tools/BuildValidator/Program.cs
Outdated
| try | ||
| // Find the embedded pdb | ||
| var originalBinaryStream = File.OpenRead(assemblyInfo.FilePath); | ||
| var originalPeReader = new PEReader(originalBinaryStream); |
There was a problem hiding this comment.
Why remove the using from these two declarations?
There was a problem hiding this comment.
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.
|
|
||
|
|
There was a problem hiding this comment.
Nit: double blank line
| var originalMdv = getMdv(originalEmit.PdbReader); | ||
| var rebuildMdv = getMdv(rebuildEmit.PdbReader); | ||
|
|
||
| Assert.True(false, $@" |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
|
|
||
| // 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, $@" |
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
File.OpenRead(assemblyInfo.FilePath) [](start = 54, length = 36)
Does PEReader.Dispose() dispose of the Stream?
There was a problem hiding this comment.
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.
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.