From 4c5181cb282950fa6d88c6dd94035287d8c53598 Mon Sep 17 00:00:00 2001 From: Kevin Halverson Date: Wed, 8 Apr 2015 14:50:18 -0700 Subject: [PATCH] Use SymReader from debugger (that supports CDI from EnC pdbs)... This involves a couple changes: - Fix signature of IENCSymbolReaderProvider.GetSymbolReader - Remove all of our "fallback" SymReader creation logic and use ISymUnmanagedReader3 when getting custom debug info --- .../ExpressionCompiler/MockSymUnmanaged.cs | 4 +- src/Test/PdbUtilities/Pdb/SymReader.cs | 4 +- .../Shared/SymUnmanagedReaderExtensions.cs | 8 +-- .../Interop/IENCSymbolReaderProvider.cs | 2 +- .../VsENCRebuildableProjectImpl.cs | 56 ++++--------------- 5 files changed, 14 insertions(+), 60 deletions(-) diff --git a/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/MockSymUnmanaged.cs b/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/MockSymUnmanaged.cs index 601730c653f..130911368d6 100644 --- a/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/MockSymUnmanaged.cs +++ b/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/MockSymUnmanaged.cs @@ -39,9 +39,7 @@ public int GetSymAttribute(int methodToken, string name, int bufferLength, out i // The EE should never be calling ISymUnmanagedReader.GetSymAttribute. // In order to account for EnC updates, it should always be calling // ISymUnmanagedReader3.GetSymAttributeByVersion instead. - // TODO (DevDiv #1145183): throw ExceptionUtilities.Unreachable; - - return GetSymAttributeByVersion(methodToken, 1, name, bufferLength, out count, customDebugInformation); + throw ExceptionUtilities.Unreachable; } public int GetSymAttributeByVersion(int methodToken, int version, string name, int bufferLength, out int count, byte[] customDebugInformation) diff --git a/src/Test/PdbUtilities/Pdb/SymReader.cs b/src/Test/PdbUtilities/Pdb/SymReader.cs index ef1bd035a72..d3ecfc66884 100644 --- a/src/Test/PdbUtilities/Pdb/SymReader.cs +++ b/src/Test/PdbUtilities/Pdb/SymReader.cs @@ -101,9 +101,7 @@ public int GetSymAttribute(int token, string name, int sizeBuffer, out int lengt // The EE should never be calling ISymUnmanagedReader.GetSymAttribute. // In order to account for EnC updates, it should always be calling // ISymUnmanagedReader3.GetSymAttributeByVersion instead. - // TODO (DevDiv #1145183): throw ExceptionUtilities.Unreachable; - - return UnversionedReader.GetSymAttribute(token, name, sizeBuffer, out lengthBuffer, buffer); + throw ExceptionUtilities.Unreachable; } public int GetSymAttributeByVersion(int methodToken, int version, string name, int bufferLength, out int count, byte[] customDebugInformation) diff --git a/src/Test/PdbUtilities/Shared/SymUnmanagedReaderExtensions.cs b/src/Test/PdbUtilities/Shared/SymUnmanagedReaderExtensions.cs index ba7e993634a..c1d65f8cad2 100644 --- a/src/Test/PdbUtilities/Shared/SymUnmanagedReaderExtensions.cs +++ b/src/Test/PdbUtilities/Shared/SymUnmanagedReaderExtensions.cs @@ -161,13 +161,7 @@ public static byte[] GetCustomDebugInfoBytes(this ISymUnmanagedReader reader, in methodToken, methodVersion, (ISymUnmanagedReader pReader, int pMethodToken, int pMethodVersion, int pBufferLength, out int pCount, byte[] pCustomDebugInfo) => - { - // TODO (DevDiv #1145183): cast should always succeed. - var pReader3 = pReader as ISymUnmanagedReader3; - return pReader3 == null - ? pReader.GetSymAttribute(pMethodToken, CdiAttributeName, pBufferLength, out pCount, pCustomDebugInfo) - : pReader3.GetSymAttributeByVersion(pMethodToken, pMethodVersion, CdiAttributeName, pBufferLength, out pCount, pCustomDebugInfo); - }); + ((ISymUnmanagedReader3)pReader).GetSymAttributeByVersion(pMethodToken, pMethodVersion, CdiAttributeName, pBufferLength, out pCount, pCustomDebugInfo)); } public static int GetUserEntryPoint(this ISymUnmanagedReader symReader) diff --git a/src/VisualStudio/Core/Def/Implementation/EditAndContinue/Interop/IENCSymbolReaderProvider.cs b/src/VisualStudio/Core/Def/Implementation/EditAndContinue/Interop/IENCSymbolReaderProvider.cs index f3e830476a1..e597b2d4e4c 100644 --- a/src/VisualStudio/Core/Def/Implementation/EditAndContinue/Interop/IENCSymbolReaderProvider.cs +++ b/src/VisualStudio/Core/Def/Implementation/EditAndContinue/Interop/IENCSymbolReaderProvider.cs @@ -10,6 +10,6 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.EditAndContinue [Guid("B69910A9-4AD6-475F-859A-5DC0B1072A5D")] internal interface IENCSymbolReaderProvider { - void GetSymbolReader([MarshalAs(UnmanagedType.IUnknown)]out object ppSymbolReader); + void GetSymbolReader(out IntPtr ppSymbolReaderMta); } } diff --git a/src/VisualStudio/Core/Def/Implementation/EditAndContinue/VsENCRebuildableProjectImpl.cs b/src/VisualStudio/Core/Def/Implementation/EditAndContinue/VsENCRebuildableProjectImpl.cs index 6cf4d5cd12c..ec9a7b9b989 100644 --- a/src/VisualStudio/Core/Def/Implementation/EditAndContinue/VsENCRebuildableProjectImpl.cs +++ b/src/VisualStudio/Core/Def/Implementation/EditAndContinue/VsENCRebuildableProjectImpl.cs @@ -87,12 +87,7 @@ internal sealed class VsENCRebuildableProjectImpl private ISymUnmanagedReader _pdbReader; - // used when the symbol reader is retrieved from the debugger: - private object _pdbReaderObj; - - // used when we can't retrive the reader from the debugger due to bug 775251 - private SymbolReaderProvider _pdbProvider; - private byte[] _pdbImage; + private IntPtr _pdbReaderMtaPointer; #endregion @@ -327,19 +322,15 @@ public int StopDebuggingPE() _committedBaseline = null; _activeStatementIds = null; - if (_pdbReaderObj != null) - { - Marshal.ReleaseComObject(_pdbReaderObj); - _pdbReaderObj = null; - } + Debug.Assert((_pdbReader == null) == (_pdbReaderMtaPointer == IntPtr.Zero)); - if (_pdbProvider != null) + if (_pdbReader != null) { - _pdbProvider.Dispose(); - _pdbProvider = null; + Marshal.ReleaseComObject(_pdbReader); + _pdbReader = null; } - _pdbReader = null; + _pdbReaderMtaPointer = IntPtr.Zero; // The HResult is ignored by the debugger. return VSConstants.S_OK; @@ -941,27 +932,8 @@ public unsafe int BuildForEnc(object pUpdatePE) Interop.IENCDebugInfo debugInfo; updater.GetENCDebugInfo(out debugInfo); -#if TODO // bug 779679: If we use a SymReader provided by the debugger the DPB may stay locked even after the debug session ends. - try - { var symbolReaderProvider = (Interop.IENCSymbolReaderProvider)debugInfo; - symbolReaderProvider.GetSymbolReader(out this.pdbReaderObj); - } - catch (InvalidCastException) // bug 775251 - { -#endif - try - { - string pdbPath = Path.ChangeExtension(_vsProject.TryGetObjOutputPath(), ".pdb"); - _pdbImage = File.ReadAllBytes(pdbPath); - } - catch (Exception) - { - return VSConstants.E_FAIL; - } -#if TODO - } -#endif + symbolReaderProvider.GetSymbolReader(out _pdbReaderMtaPointer); _committedBaseline = EmitBaseline.CreateInitialBaseline(_metadata, GetBaselineEncDebugInfo); } @@ -1078,17 +1050,9 @@ private EditAndContinueMethodDebugInformation GetBaselineEncDebugInfo(MethodDefi if (_pdbReader == null) { - if (_pdbReaderObj != null) - { - _pdbReader = (ISymUnmanagedReader)_pdbReaderObj; - } - else - { - Debug.Assert(_pdbImage != null); - _pdbProvider = SymbolReaderProvider.Create(_pdbImage); - _pdbReader = _pdbProvider.SymbolReader; - _pdbImage = null; - } + Debug.Assert(_pdbReaderMtaPointer != IntPtr.Zero); + object pdbReaderObj = Marshal.GetObjectForIUnknown(_pdbReaderMtaPointer); + _pdbReader = (ISymUnmanagedReader)pdbReaderObj; } int methodToken = MetadataTokens.GetToken(methodHandle); -- GitLab