提交 8a60a86b 编写于 作者: T Tomas Matousek

Avoid opening PDB writer on existing PDB file

上级 54346555
......@@ -20,15 +20,13 @@ private sealed class CompilerEmitStreamProvider : Compilation.EmitStreamProvider
private readonly CommonCompiler _compiler;
private readonly string _filePath;
private readonly bool _streamCreatedByNativePdbWriter;
private Stream _lazyStream;
internal CompilerEmitStreamProvider(CommonCompiler compiler, string filePath, bool streamCreatedByNativePdbWriter)
internal CompilerEmitStreamProvider(CommonCompiler compiler, string filePath)
{
_compiler = compiler;
_filePath = filePath;
_streamCreatedByNativePdbWriter = streamCreatedByNativePdbWriter;
_lazyStream = s_uninitialized;
}
......@@ -45,7 +43,7 @@ public override Stream GetStream(DiagnosticBag diagnostics)
{
if (_lazyStream == s_uninitialized)
{
_lazyStream = _streamCreatedByNativePdbWriter ? null : OpenFile(_filePath, diagnostics);
_lazyStream = OpenFile(_filePath, diagnostics);
}
return _lazyStream;
......
......@@ -416,8 +416,8 @@ private int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, Cancellat
WithOutputNameOverride(outputName).
WithPdbFilePath(finalPdbFilePath);
using (var peStreamProvider = new CompilerEmitStreamProvider(this, finalOutputPath, streamCreatedByNativePdbWriter: false))
using (var pdbStreamProviderOpt = Arguments.EmitPdb ? new CompilerEmitStreamProvider(this, finalOutputPath, streamCreatedByNativePdbWriter: true) : null)
using (var peStreamProvider = new CompilerEmitStreamProvider(this, finalOutputPath))
using (var pdbStreamProviderOpt = Arguments.EmitPdb ? new CompilerEmitStreamProvider(this, finalPdbFilePath) : null)
{
emitResult = compilation.Emit(
peStreamProvider,
......
......@@ -1641,6 +1641,7 @@ private static EmitResult ToEmitResultAndFree(DiagnosticBag diagnostics, bool su
pdbStream = pdbStreamProvider.GetStream(diagnostics);
if (pdbStream == null)
{
Debug.Assert(diagnostics.HasAnyErrors());
return null;
}
......@@ -1648,8 +1649,8 @@ private static EmitResult ToEmitResultAndFree(DiagnosticBag diagnostics, bool su
// Native PDB writer is able to update an existing stream.
// It checks for length to determine whether the given stream has existing data to be updated,
// or whether it should start writing PDB data from scratch. Thus if not writing to a seekable empty stream ,
// let's create an in-memory temp stream for the PDB writer and copy all data to the actual stream at once at the end.
// or whether it should start writing PDB data from scratch. Thus if not writing to a seekable empty stream,
// we have to create an in-memory temp stream for the PDB writer and copy all data to the actual stream at once at the end.
if (!retStream.CanSeek || retStream.Length != 0)
{
retStream = pdbTempStream = new MemoryStream();
......@@ -1725,7 +1726,7 @@ private static EmitResult ToEmitResultAndFree(DiagnosticBag diagnostics, bool su
{
// Note: Native PDB writer may operate on the underlying stream during disposal.
// So close it here before we read data from the underlying stream.
nativePdbWriter.WritePdbToOutput();
nativePdbWriter?.WritePdbToOutput();
pdbTempStream.Position = 0;
pdbTempStream.CopyTo(pdbStream);
......
......@@ -75,8 +75,7 @@ public void Dispose()
}
/// <summary>
/// Close the PDB writer and write the contents to the stream provided by <see cref="_streamProvider"/>
/// or file name specified by <see cref="_fileName"/> value if no stream has been provided.
/// Close the PDB writer and write the PDB data to the stream provided by <see cref="_streamProvider"/>.
/// </summary>
public void WritePdbToOutput()
{
......@@ -559,14 +558,17 @@ private static Type GetCorSymWriterSxSType()
public void SetMetadataEmitter(MetadataWriter metadataWriter)
{
Stream streamOpt = _streamProvider();
Stream stream = _streamProvider() ?? new System.IO.MemoryStream();
try
{
var instance = (ISymUnmanagedWriter2)(_symWriterFactory != null ? _symWriterFactory() : Activator.CreateInstance(GetCorSymWriterSxSType()));
var comStream = (streamOpt != null) ? new ComStreamWrapper(streamOpt) : null;
instance.Initialize(new PdbMetadataWrapper(metadataWriter), _fileName, comStream, fullBuild: true);
// Important: If the stream is not specified or if it is non-empty the SymWriter appends data to it (provided it contains valid PDB)
// and the resulting PDB has Age = existing_age + 1.
Debug.Assert(stream.Length == 0);
instance.Initialize(new PdbMetadataWrapper(metadataWriter), _fileName, new ComStreamWrapper(stream), fullBuild: true);
_metadataWriter = metadataWriter;
_symWriter = instance;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册