public void Dispose() { // If the underlying symbol reader supports an explicit dispose interface to release // it's resources, then call it. (rawReader as ISymUnmanagedDispose)?.Destroy(); this.rawReader = null; }
public PDBReader(string assemblyPath) { object metaDataImport = null; IMetaDataDispenser dispenser = null; try { Guid metaDataImportIID = new Guid(IMetaDataImportGuid); dispenser = (IMetaDataDispenser)(new MetaDataDispenser()); dispenser.OpenScope(assemblyPath, 0, ref metaDataImportIID, out metaDataImport); this.symReader = (ISymUnmanagedReader)(new CorSymReader_SxS()); this.symReader.Initialize(metaDataImport, assemblyPath, null, null); } finally { // Release COM objects so that files don't remain locked. if (metaDataImport != null) Marshal.ReleaseComObject(metaDataImport); if (dispenser != null) Marshal.ReleaseComObject(dispenser); } }
private PdbToXmlConverter(XmlWriter writer, ISymUnmanagedReader symReader, MetadataReader metadataReader, PdbToXmlOptions options) { _symReader = symReader; _metadataReader = metadataReader; _writer = writer; _options = options; }
private int[][] GetMethodTokensForEachLine(ISymUnmanagedReader symReader, ISymUnmanagedDocument symDocument, int minZeroBasedLine, int maxZeroBasedLine) { var result = new List<int[]>(); for (int line = minZeroBasedLine; line <= maxZeroBasedLine; line++) { int[] allMethodTokens = GetMethodTokensFromDocumentPosition(symReader, symDocument, line, 0); ISymUnmanagedMethod method; int hr = symReader.GetMethodFromDocumentPosition(symDocument, line, 1, out method); if (hr != HResult.S_OK) { Assert.Equal(HResult.E_FAIL, hr); Assert.Equal(0, allMethodTokens.Length); } else { int primaryToken; Assert.Equal(HResult.S_OK, method.GetToken(out primaryToken)); Assert.Equal(primaryToken, allMethodTokens.First()); } result.Add(allMethodTokens); } return result.ToArray(); }
public unsafe static ModuleInstance Create( PEMemoryBlock metadata, Guid moduleVersionId, ISymUnmanagedReader symReader = null) { return Create((IntPtr)metadata.Pointer, metadata.Length, moduleVersionId, symReader); }
internal SymReader(byte[] pdbBytes, ImmutableDictionary<string, byte[]> constantSignaturesOpt = null) { _reader = SymUnmanagedReaderExtensions.CreateReader( new MemoryStream(pdbBytes), PDB::Roslyn.Test.PdbUtilities.DummyMetadataImport.Instance); _constantSignaturesOpt = constantSignaturesOpt; }
private void Dispose() { if (this.symReader != null) { Marshal.ReleaseComObject(this.symReader); this.symReader = null; } }
public void Dispose() { if (_rawReader != null) { Marshal.ReleaseComObject(_rawReader); _rawReader = null; } }
public void Dispose() { if (this.symReader != null) { ((IDisposable)this.symReader).Dispose(); this.symReader = null; this.rawReader = null; } }
public static ModuleInstance Create( IntPtr metadataAddress, int metadataLength, Guid moduleVersionId, ISymUnmanagedReader symReader = null) { return new ModuleInstance( metadata: null, moduleVersionId: moduleVersionId, metadataLength: metadataLength, metadataAddress: metadataAddress, symReader: symReader, includeLocalSignatures: false); }
private void TestGetMethodFromDocumentPosition( ISymUnmanagedReader symReader, ISymUnmanagedDocument symDocument, int zeroBasedLine, int zeroBasedColumn, int expectedToken) { ISymUnmanagedMethod method; Assert.Equal(HResult.S_OK, symReader.GetMethodFromDocumentPosition(symDocument, zeroBasedLine, zeroBasedColumn, out method)); int token; Assert.Equal(HResult.S_OK, method.GetToken(out token)); Assert.Equal(expectedToken, token); }
public SymbolWriterClass(EnCManager manager,ITokenTranslator transl) { // Create the writer from the COM catalog Type writerType = Type.GetTypeFromCLSID(typeof(CorSymWriter_SxSClass).GUID); object comWriterObj = Activator.CreateInstance(writerType); Type readerType = Type.GetTypeFromCLSID(typeof(CorSymReader_SxSClass).GUID); object comReaderObj = Activator.CreateInstance(readerType); mWriter = (ISymUnmanagedWriter2)comWriterObj; mReader = (ISymUnmanagedReader)comReaderObj; this.manager = manager; this.stream = new CorMemStream(); this.translator = transl; State = WriterState.NotIninitialized; }
private void TestGetDocument(ISymUnmanagedReader symReader, string name, string expectedUrl) { ISymUnmanagedDocument document; if (expectedUrl != null) { // guids are ignored Assert.Equal(HResult.S_OK, symReader.GetDocument(name, Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), out document)); ValidateDocumentUrl(document, expectedUrl); } else { // guids are ignored Assert.Equal(HResult.S_FALSE, symReader.GetDocument(name, Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), out document)); Assert.Null(document); } }
internal RuntimeInstance CreateRuntimeInstance( string assemblyName, ImmutableArray<MetadataReference> references, byte[] exeBytes, ISymUnmanagedReader symReader, bool includeLocalSignatures = true) { var exeReference = AssemblyMetadata.CreateFromImage(exeBytes).GetReference(display: assemblyName); var modulesBuilder = ArrayBuilder<ModuleInstance>.GetInstance(); // Create modules for the references modulesBuilder.AddRange(references.Select(r => r.ToModuleInstance(fullImage: null, symReader: null, includeLocalSignatures: includeLocalSignatures))); // Create a module for the exe. modulesBuilder.Add(exeReference.ToModuleInstance(exeBytes, symReader, includeLocalSignatures: includeLocalSignatures)); var modules = modulesBuilder.ToImmutableAndFree(); modules.VerifyAllModules(); var instance = new RuntimeInstance(modules); _runtimeInstances.Add(instance); return instance; }
private int[] GetMethodTokensFromDocumentPosition( ISymUnmanagedReader symReader, ISymUnmanagedDocument symDocument, int zeroBasedLine, int zeroBasedColumn) { int count; Assert.Equal(HResult.S_OK, symReader.GetMethodsFromDocumentPosition(symDocument, zeroBasedLine, zeroBasedColumn, 0, out count, null)); var methods = new ISymUnmanagedMethod[count]; int count2; Assert.Equal(HResult.S_OK, symReader.GetMethodsFromDocumentPosition(symDocument, zeroBasedLine, zeroBasedColumn, count, out count2, methods)); Assert.Equal(count, count2); return methods.Select(m => { int token; Assert.Equal(HResult.S_OK, m.GetToken(out token)); return token; }).ToArray(); }
internal static void GetContextState( RuntimeInstance runtime, string methodOrTypeName, out ImmutableArray<MetadataBlock> blocks, out Guid moduleVersionId, out ISymUnmanagedReader symReader, out int methodOrTypeToken, out int localSignatureToken) { var moduleInstances = runtime.Modules; blocks = moduleInstances.SelectAsArray(m => m.MetadataBlock); var compilation = blocks.ToCompilation(); var methodOrType = GetMethodOrTypeBySignature(compilation, methodOrTypeName); var module = (PEModuleSymbol)methodOrType.ContainingModule; var id = module.Module.GetModuleVersionIdOrThrow(); var moduleInstance = moduleInstances.First(m => m.ModuleVersionId == id); moduleVersionId = id; symReader = (ISymUnmanagedReader)moduleInstance.SymReader; EntityHandle methodOrTypeHandle; if (methodOrType.Kind == SymbolKind.Method) { methodOrTypeHandle = ((PEMethodSymbol)methodOrType).Handle; localSignatureToken = moduleInstance.GetLocalSignatureToken((MethodDefinitionHandle)methodOrTypeHandle); } else { methodOrTypeHandle = ((PENamedTypeSymbol)methodOrType).Handle; localSignatureToken = -1; } MetadataReader reader = null; // null should be ok methodOrTypeToken = reader.GetToken(methodOrTypeHandle); }
public PDBReader(string assemblyPath) { object unknown = null; System.Workflow.ComponentModel.Compiler.IMetaDataDispenser o = null; try { Guid riid = new Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44"); o = (System.Workflow.ComponentModel.Compiler.IMetaDataDispenser) new System.Workflow.ComponentModel.Compiler.MetaDataDispenser(); o.OpenScope(assemblyPath, 0, ref riid, out unknown); this.symReader = (ISymUnmanagedReader) new CorSymReader_SxS(); this.symReader.Initialize(unknown, assemblyPath, null, null); } finally { if (unknown != null) { Marshal.ReleaseComObject(unknown); } if (o != null) { Marshal.ReleaseComObject(o); } } }
public static void Initialize(this ISymUnmanagedReader instance, object importer, IntPtr filename, IntPtr searchPath, IStream pIStream) { instance.__Initialize(importer, filename, searchPath, pIStream); }
public static void GetSymbolStoreFileName(this ISymUnmanagedReader instance, uint cchName, out uint pcchName, IntPtr szName) { instance.__GetSymbolStoreFileName(cchName, out pcchName, szName); }
public static uint GetUserEntryPoint(this ISymUnmanagedReader instance) { return(instance.__GetUserEntryPoint()); }
public static void GetSymAttribute(this ISymUnmanagedReader instance, uint parent, IntPtr name, uint cBuffer, out uint pcBuffer, IntPtr buffer) { instance.__GetSymAttribute(parent, name, cBuffer, out pcBuffer, buffer); }
public int StopDebuggingPE() { try { log.Write("Exit Debug Mode: project '{0}'", _vsProject.DisplayName); Debug.Assert(s_breakStateEnteredProjects.Count == 0); // Clear the solution stored while projects were entering break mode. // It should be cleared as soon as all tracked projects enter the break mode // but if the entering break mode fails for some projects we should avoid leaking the solution. Debug.Assert(s_breakStateEntrySolution == null); s_breakStateEntrySolution = null; // EnC service is global (per solution), but the debugger calls this for each project. // Avoid ending the debug session if it has already been ended. if (_encService.DebuggingSession != null) { _encService.OnBeforeDebuggingStateChanged(DebuggingState.Run, DebuggingState.Design); _encService.EndDebuggingSession(); LogEncSession(); s_encDebuggingSessionInfo = null; s_readOnlyDocumentTracker.Dispose(); s_readOnlyDocumentTracker = null; } if (_metadata != null) { _metadata.Dispose(); _metadata = null; s_debugStateProjectCount--; } else { // an error might have been reported: _diagnosticProvider.ClearDiagnostics(_encService.DebuggingSession, _vsProject.VisualStudioWorkspace, EditAndContinueDiagnosticUpdateSource.DebuggerErrorId, _vsProject.Id, documentId: null); } _activeMethods = null; _exceptionRegions = null; _committedBaseline = null; _activeStatementIds = null; Debug.Assert((_pdbReaderObjAsStream == IntPtr.Zero) || (_pdbReader == null)); if (_pdbReader != null) { Marshal.ReleaseComObject(_pdbReader); _pdbReader = null; } // The HResult is ignored by the debugger. return VSConstants.S_OK; } catch (Exception e) when (FatalError.ReportWithoutCrash(e)) { return VSConstants.E_FAIL; } }
public void UnloadSymbols() { if (symReader != null) { ((ISymUnmanagedDispose)symReader).Destroy(); symReader = null; } }
public void Dispose() { // Release our unmanaged resources m_reader = null; }
/// <summary> /// Get the blob of binary custom debug info for a given method. /// TODO: consume <paramref name="methodVersion"/> (DevDiv #1068138). /// </summary> public static byte[] GetCustomDebugInfoBytes(this ISymUnmanagedReader reader, int methodToken, int methodVersion) { return(GetItems(reader, new SymbolToken(methodToken), CdiAttributeName, (ISymUnmanagedReader a, SymbolToken b, string c, int d, out int e, byte[] f) => a.GetSymAttribute(b, c, d, out e, f))); }
/// <summary> /// Get the import strings for a given method, following forward pointers as necessary. /// </summary> /// <returns> /// For each namespace enclosing the method, a list of import strings, innermost to outermost. /// There should always be at least one entry, for the global namespace. /// </returns> public static ImmutableArray <ImmutableArray <string> > GetCSharpGroupedImportStrings(this ISymUnmanagedReader reader, int methodToken, int methodVersion, out ImmutableArray <string> externAliasStrings) { externAliasStrings = default(ImmutableArray <string>); ImmutableArray <short> groupSizes = default(ImmutableArray <short>); bool seenForward = false; RETRY: byte[] bytes = reader.GetCustomDebugInfoBytes(methodToken, methodVersion); if (bytes == null) { return(default(ImmutableArray <ImmutableArray <string> >)); } foreach (var record in GetCustomDebugInfoRecords(bytes)) { switch (record.Kind) { case CustomDebugInfoKind.UsingInfo: if (!groupSizes.IsDefault) { throw new InvalidOperationException(string.Format("Expected at most one Using record for method {0}", FormatMethodToken(methodToken))); } groupSizes = DecodeUsingRecord(record.Data); break; case CustomDebugInfoKind.ForwardInfo: if (!externAliasStrings.IsDefault) { throw new InvalidOperationException(string.Format("Did not expect both Forward and ForwardToModule records for method {0}", FormatMethodToken(methodToken))); } methodToken = DecodeForwardRecord(record.Data); // Follow at most one forward link (as in FUNCBRECEE::ensureNamespaces). // NOTE: Dev11 may produce chains of forward links (e.g. for System.Collections.Immutable). if (!seenForward) { seenForward = true; goto RETRY; } break; case CustomDebugInfoKind.ForwardToModuleInfo: if (!externAliasStrings.IsDefault) { throw new InvalidOperationException(string.Format("Expected at most one ForwardToModule record for method {0}", FormatMethodToken(methodToken))); } int moduleInfoMethodToken = DecodeForwardToModuleRecord(record.Data); ImmutableArray <string> allModuleInfoImportStrings = reader.GetMethodByVersion(moduleInfoMethodToken, methodVersion).GetImportStrings(); ArrayBuilder <string> externAliasBuilder = ArrayBuilder <string> .GetInstance(); foreach (string importString in allModuleInfoImportStrings) { if (IsCSharpExternAliasInfo(importString)) { externAliasBuilder.Add(importString); } } externAliasStrings = externAliasBuilder.ToImmutableAndFree(); break; } } if (groupSizes.IsDefault) { // This can happen in malformed PDBs (e.g. chains of forwards). return(default(ImmutableArray <ImmutableArray <string> >)); } var method = reader.GetMethodByVersion(methodToken, methodVersion); if (method == null) { return(default(ImmutableArray <ImmutableArray <string> >)); } ImmutableArray <string> importStrings = method.GetImportStrings(); int numImportStrings = importStrings.Length; ArrayBuilder <ImmutableArray <string> > resultBuilder = ArrayBuilder <ImmutableArray <string> > .GetInstance(groupSizes.Length); ArrayBuilder <string> groupBuilder = ArrayBuilder <string> .GetInstance(); int pos = 0; foreach (short groupSize in groupSizes) { for (int i = 0; i < groupSize; i++, pos++) { if (pos >= numImportStrings) { throw new InvalidOperationException(string.Format("Group size indicates more imports than there are import strings (method {0}).", FormatMethodToken(methodToken))); } string importString = importStrings[pos]; if (IsCSharpExternAliasInfo(importString)) { throw new InvalidOperationException(string.Format("Encountered extern alias info before all import strings were consumed (method {0}).", FormatMethodToken(methodToken))); } groupBuilder.Add(importString); } resultBuilder.Add(groupBuilder.ToImmutable()); groupBuilder.Clear(); } if (externAliasStrings.IsDefault) { Debug.Assert(groupBuilder.Count == 0); // Extern alias detail strings (prefix "Z") are not included in the group counts. for (; pos < numImportStrings; pos++) { string importString = importStrings[pos]; if (!IsCSharpExternAliasInfo(importString)) { throw new InvalidOperationException(string.Format("Expected only extern alias info strings after consuming the indicated number of imports (method {0}).", FormatMethodToken(methodToken))); } groupBuilder.Add(importString); } externAliasStrings = groupBuilder.ToImmutableAndFree(); } else { groupBuilder.Free(); if (pos < numImportStrings) { throw new InvalidOperationException(string.Format("Group size indicates fewer imports than there are import strings (method {0}).", FormatMethodToken(methodToken))); } } return(resultBuilder.ToImmutableAndFree()); }
private TempPdbReader(ISymUnmanagedReader rawReader) { _rawReader = rawReader; }
private static void ReadCSharpNativeImportsInfo( ISymUnmanagedReader reader, EESymbolProvider <TTypeSymbol, TLocalSymbol> symbolProvider, int methodToken, int methodVersion, out ImmutableArray <ImmutableArray <ImportRecord> > importRecordGroups, out ImmutableArray <ExternAliasRecord> externAliasRecords) { ImmutableArray <string> externAliasStrings; var importStringGroups = reader.GetCSharpGroupedImportStrings(methodToken, methodVersion, out externAliasStrings); Debug.Assert(importStringGroups.IsDefault == externAliasStrings.IsDefault); ArrayBuilder <ImmutableArray <ImportRecord> > importRecordGroupBuilder = null; ArrayBuilder <ExternAliasRecord> externAliasRecordBuilder = null; if (!importStringGroups.IsDefault) { importRecordGroupBuilder = ArrayBuilder <ImmutableArray <ImportRecord> > .GetInstance(importStringGroups.Length); foreach (var importStringGroup in importStringGroups) { var groupBuilder = ArrayBuilder <ImportRecord> .GetInstance(importStringGroup.Length); foreach (var importString in importStringGroup) { ImportRecord record; if (TryCreateImportRecordFromCSharpImportString(symbolProvider, importString, out record)) { groupBuilder.Add(record); } else { Debug.WriteLine($"Failed to parse import string {importString}"); } } importRecordGroupBuilder.Add(groupBuilder.ToImmutableAndFree()); } if (!externAliasStrings.IsDefault) { externAliasRecordBuilder = ArrayBuilder <ExternAliasRecord> .GetInstance(externAliasStrings.Length); foreach (string externAliasString in externAliasStrings) { string alias; string externAlias; string target; ImportTargetKind kind; if (!CustomDebugInfoReader.TryParseCSharpImportString(externAliasString, out alias, out externAlias, out target, out kind)) { Debug.WriteLine($"Unable to parse extern alias '{externAliasString}'"); continue; } Debug.Assert(kind == ImportTargetKind.Assembly, "Programmer error: How did a non-assembly get in the extern alias list?"); Debug.Assert(alias != null); // Name of the extern alias. Debug.Assert(externAlias == null); // Not used. Debug.Assert(target != null); // Name of the target assembly. AssemblyIdentity targetIdentity; if (!AssemblyIdentity.TryParseDisplayName(target, out targetIdentity)) { Debug.WriteLine($"Unable to parse target of extern alias '{externAliasString}'"); continue; } externAliasRecordBuilder.Add(new ExternAliasRecord(alias, targetIdentity)); } } } importRecordGroups = importRecordGroupBuilder?.ToImmutableAndFree() ?? ImmutableArray <ImmutableArray <ImportRecord> > .Empty; externAliasRecords = externAliasRecordBuilder?.ToImmutableAndFree() ?? ImmutableArray <ExternAliasRecord> .Empty; }
private static void ReadVisualBasicImportsDebugInfo( ISymUnmanagedReader reader, int methodToken, int methodVersion, out ImmutableArray <ImmutableArray <ImportRecord> > importRecordGroups, out string defaultNamespaceName) { importRecordGroups = ImmutableArray <ImmutableArray <ImportRecord> > .Empty; var importStrings = CustomDebugInfoReader.GetVisualBasicImportStrings( methodToken, KeyValuePair.Create(reader, methodVersion), (token, arg) => GetImportStrings(arg.Key, token, arg.Value)); if (importStrings.IsDefault) { defaultNamespaceName = ""; return; } defaultNamespaceName = null; var projectLevelImportRecords = ArrayBuilder <ImportRecord> .GetInstance(); var fileLevelImportRecords = ArrayBuilder <ImportRecord> .GetInstance(); foreach (string importString in importStrings) { Debug.Assert(importString != null); if (importString.Length > 0 && importString[0] == '*') { string alias = null; string target = null; ImportTargetKind kind = 0; VBImportScopeKind scope = 0; if (!CustomDebugInfoReader.TryParseVisualBasicImportString(importString, out alias, out target, out kind, out scope)) { Debug.WriteLine($"Unable to parse import string '{importString}'"); continue; } else if (kind == ImportTargetKind.Defunct) { continue; } Debug.Assert(alias == null); // The default namespace is never aliased. Debug.Assert(target != null); Debug.Assert(kind == ImportTargetKind.DefaultNamespace); // We only expect to see one of these, but it looks like ProcedureContext::LoadImportsAndDefaultNamespaceNormal // implicitly uses the last one if there are multiple. Debug.Assert(defaultNamespaceName == null); defaultNamespaceName = target; } else { ImportRecord importRecord; VBImportScopeKind scope = 0; if (TryCreateImportRecordFromVisualBasicImportString(importString, out importRecord, out scope)) { if (scope == VBImportScopeKind.Project) { projectLevelImportRecords.Add(importRecord); } else { Debug.Assert(scope == VBImportScopeKind.File || scope == VBImportScopeKind.Unspecified); fileLevelImportRecords.Add(importRecord); } } else { Debug.WriteLine($"Failed to parse import string {importString}"); } } } importRecordGroups = ImmutableArray.Create( fileLevelImportRecords.ToImmutableAndFree(), projectLevelImportRecords.ToImmutableAndFree()); defaultNamespaceName = defaultNamespaceName ?? ""; }
public static void Dispose(this ISymUnmanagedReader symReader) => ((ISymUnmanagedDispose)symReader)?.Destroy();
public void UnloadSymbols() { if (symReader != null) { // The interface is not always supported, I did not manage to reproduce it, but the // last callbacks in the user's log were UnloadClass and UnloadModule so I guess // it has something to do with dynamic modules. if (symReader is ISymUnmanagedDispose) { ((ISymUnmanagedDispose)symReader).Destroy(); } symReader = null; } }
public Handle(ISymUnmanagedReader reader) { _reader = reader; }
public static void GetMethodsFromDocumentPosition(this ISymUnmanagedReader instance, ISymUnmanagedDocument document, uint line, uint column, uint cMethod, out uint pcMethod, IntPtr pRetVal) { instance.__GetMethodsFromDocumentPosition(document, line, column, cMethod, out pcMethod, pRetVal); }
private UnmanagedPdbSymbolReader(ISymUnmanagedReader symUnmanagedReader) { _symUnmanagedReader = symUnmanagedReader; }
public static ImmutableArray <ISymUnmanagedMethod> GetMethodsInDocument(this ISymUnmanagedReader reader, ISymUnmanagedDocument symDocument) { return(ToImmutableOrEmpty(GetItems((ISymUnmanagedReader2)reader, symDocument, (ISymUnmanagedReader2 a, ISymUnmanagedDocument b, int c, out int d, ISymUnmanagedMethod[] e) => a.GetMethodsInDocument(b, c, out d, e)))); }
public unsafe static MethodDebugInfo <TTypeSymbol, TLocalSymbol> ReadMethodDebugInfo( ISymUnmanagedReader symReader, EESymbolProvider <TTypeSymbol, TLocalSymbol> symbolProviderOpt, // TODO: only null in DTEE case where we looking for default namesapace int methodToken, int methodVersion, int ilOffset, bool isVisualBasicMethod) { // no symbols if (symReader == null) { return(None); } var symReader4 = symReader as ISymUnmanagedReader4; if (symReader4 != null) // TODO: VB Portable PDBs { byte *metadata; int size; // TODO: version int hr = symReader4.GetPortableDebugMetadata(out metadata, out size); SymUnmanagedReaderExtensions.ThrowExceptionForHR(hr); if (metadata != null) { var mdReader = new MetadataReader(metadata, size); try { return(ReadFromPortable(mdReader, methodToken, ilOffset, symbolProviderOpt, isVisualBasicMethod)); } catch (BadImageFormatException) { // bad CDI, ignore return(None); } } } var allScopes = ArrayBuilder <ISymUnmanagedScope> .GetInstance(); var containingScopes = ArrayBuilder <ISymUnmanagedScope> .GetInstance(); try { ImmutableArray <HoistedLocalScopeRecord> hoistedLocalScopeRecords; ImmutableArray <ImmutableArray <ImportRecord> > importRecordGroups; ImmutableArray <ExternAliasRecord> externAliasRecords; ImmutableDictionary <int, ImmutableArray <bool> > dynamicLocalMap; ImmutableDictionary <string, ImmutableArray <bool> > dynamicLocalConstantMap; string defaultNamespaceName; var symMethod = symReader.GetMethodByVersion(methodToken, methodVersion); if (symMethod != null) { symMethod.GetAllScopes(allScopes, containingScopes, ilOffset, isScopeEndInclusive: isVisualBasicMethod); } if (isVisualBasicMethod) { ReadVisualBasicImportsDebugInfo( symReader, methodToken, methodVersion, out importRecordGroups, out defaultNamespaceName); hoistedLocalScopeRecords = ImmutableArray <HoistedLocalScopeRecord> .Empty; externAliasRecords = ImmutableArray <ExternAliasRecord> .Empty; dynamicLocalMap = null; dynamicLocalConstantMap = null; } else { Debug.Assert(symbolProviderOpt != null); ReadCSharpNativeImportsInfo( symReader, symbolProviderOpt, methodToken, methodVersion, out importRecordGroups, out externAliasRecords); ReadCSharpNativeCustomDebugInfo( symReader, methodToken, methodVersion, allScopes, out hoistedLocalScopeRecords, out dynamicLocalMap, out dynamicLocalConstantMap); defaultNamespaceName = ""; } var constantsBuilder = ArrayBuilder <TLocalSymbol> .GetInstance(); if (symbolProviderOpt != null) // TODO { GetConstants(constantsBuilder, symbolProviderOpt, containingScopes, dynamicLocalConstantMap); } var reuseSpan = GetReuseSpan(allScopes, ilOffset, isVisualBasicMethod); return(new MethodDebugInfo <TTypeSymbol, TLocalSymbol>( hoistedLocalScopeRecords, importRecordGroups, externAliasRecords, dynamicLocalMap, defaultNamespaceName, containingScopes.GetLocalNames(), constantsBuilder.ToImmutableAndFree(), reuseSpan)); } catch (InvalidOperationException) { // bad CDI, ignore return(None); } finally { allScopes.Free(); containingScopes.Free(); } }
public static SymbolReader Create(PdbReaderContext pdbContext, MD.Metadata metadata, DataReaderFactory pdbStream) { ISymUnmanagedReader unmanagedReader = null; SymbolReaderImpl symReader = null; ReaderMetaDataImport mdImporter = null; DataReaderIStream comPdbStream = null; bool error = true; try { if (pdbStream is null) { return(null); } var debugDir = pdbContext.CodeViewDebugDirectory; if (debugDir is null) { return(null); } if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) { return(null); } unmanagedReader = CreateSymUnmanagedReader(pdbContext.Options); if (unmanagedReader is null) { return(null); } mdImporter = new ReaderMetaDataImport(metadata); comPdbStream = new DataReaderIStream(pdbStream); int hr = unmanagedReader.Initialize(mdImporter, null, null, comPdbStream); if (hr < 0) { return(null); } symReader = new SymbolReaderImpl(unmanagedReader, new object[] { pdbStream, mdImporter, comPdbStream }); if (!symReader.MatchesModule(pdbGuid, debugDir.TimeDateStamp, age)) { return(null); } error = false; return(symReader); } catch (IOException) { } catch (InvalidCastException) { } catch (COMException) { } finally { if (error) { pdbStream?.Dispose(); symReader?.Dispose(); mdImporter?.Dispose(); comPdbStream?.Dispose(); (unmanagedReader as ISymUnmanagedDispose)?.Destroy(); } } return(null); }
public static ISymUnmanagedMethod GetMethod(this ISymUnmanagedReader reader, int methodToken) { return(GetMethodByVersion(reader, methodToken, methodVersion: 1)); }
public static void GetDocuments(this ISymUnmanagedReader instance, uint cDocs, out uint pcDocs, ISymUnmanagedDocument[] pDocs) { instance.__GetDocuments(cDocs, out pcDocs, pDocs); ProcessOutParameter(pDocs); }
/// <summary> /// Constructor /// </summary> /// <param name="reader">An unmanaged symbol reader</param> public SymbolReader(ISymUnmanagedReader reader) { if (reader == null) throw new ArgumentNullException("reader"); this.reader = reader; }
public static void GetGlobalVariables(this ISymUnmanagedReader instance, uint cVars, out uint pcVars, IntPtr pVars) { instance.__GetGlobalVariables(cVars, out pcVars, pVars); }
/// <summary> /// 'ILStart <= ILOffset <= ILEnd' and this range includes at least /// the returned area of source code. (May incude some extra compiler generated IL too) /// </summary> internal static SourcecodeSegment Resolve(Module module, ICorDebugFunction corFunction, int offset) { ISymUnmanagedReader symReader = module.SymReader; if (symReader == null) { return(null); // No symbols } ISymUnmanagedMethod symMethod; try { symMethod = symReader.GetMethod(corFunction.GetToken()); } catch (COMException) { // Can not find the method // eg. Compiler generated constructors are not in symbol store return(null); } if (symMethod == null) { return(null); } uint sequencePointCount = symMethod.GetSequencePointCount(); SequencePoint[] sequencePoints = symMethod.GetSequencePoints(); // Get i for which: offsets[i] <= offset < offsets[i + 1] // or fallback to first element if offset < offsets[0] for (int i = (int)sequencePointCount - 1; i >= 0; i--) // backwards { if ((int)sequencePoints[i].Offset <= offset || i == 0) { // Set inforamtion about current IL range int codeSize = (int)corFunction.GetILCode().GetSize(); int ilStart = (int)sequencePoints[i].Offset; int ilEnd = (i + 1 < sequencePointCount) ? (int)sequencePoints[i + 1].Offset : codeSize; // 0xFeeFee means "code generated by compiler" // If we are in generated sequence use to closest real one instead, // extend the ILStart and ILEnd to include the 'real' sequence // Look ahead for 'real' sequence while (i + 1 < sequencePointCount && sequencePoints[i].Line == 0xFeeFee) { i++; ilEnd = (i + 1 < sequencePointCount) ? (int)sequencePoints[i + 1].Offset : codeSize; } // Look back for 'real' sequence while (i - 1 >= 0 && sequencePoints[i].Line == 0xFeeFee) { i--; ilStart = (int)sequencePoints[i].Offset; } // Wow, there are no 'real' sequences if (sequencePoints[i].Line == 0xFeeFee) { return(null); } List <int> stepRanges = new List <int>(); for (int j = 0; j < sequencePointCount; j++) { // Step over compiler generated sequences and current statement // 0xFeeFee means "code generated by compiler" if (sequencePoints[j].Line == 0xFeeFee || j == i) { // Add start offset or remove last end (to connect two ranges into one) if (stepRanges.Count > 0 && stepRanges[stepRanges.Count - 1] == sequencePoints[j].Offset) { stepRanges.RemoveAt(stepRanges.Count - 1); } else { stepRanges.Add((int)sequencePoints[j].Offset); } // Add end offset | handle last sequence point if (j + 1 < sequencePointCount) { stepRanges.Add((int)sequencePoints[j + 1].Offset); } else { stepRanges.Add(codeSize); } } } SourcecodeSegment segment = new SourcecodeSegment(); segment.module = module; segment.filename = GetFilenameFromSymDocument(module, sequencePoints[i].Document); segment.checkSum = sequencePoints[i].Document.GetCheckSum(); segment.startLine = (int)sequencePoints[i].Line; segment.startColumn = (int)sequencePoints[i].Column; segment.endLine = (int)sequencePoints[i].EndLine; segment.endColumn = (int)sequencePoints[i].EndColumn; segment.corFunction = corFunction; segment.ilStart = ilStart; segment.ilEnd = ilEnd; segment.stepRanges = stepRanges.ToArray(); // VB.NET sometimes produces temporary files which it then deletes // (eg 17d14f5c-a337-4978-8281-53493378c1071.vb) string filename = Path.GetFileName(segment.filename); if (filename.Length == 40 && filename.EndsWith(".vb")) { bool guidName = true; foreach (char c in filename.Substring(0, filename.Length - 3)) { if (('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') || (c == '-')) { guidName = true; } else { guidName = false; break; } } if (guidName) { return(null); } } return(segment); } } return(null); }
public static void GetNamespaces(this ISymUnmanagedReader instance, uint cNameSpaces, out uint pcNameSpaces, ISymUnmanagedNamespace[] namespaces) { instance.__GetNamespaces(cNameSpaces, out pcNameSpaces, namespaces); ProcessOutParameter(namespaces); }
public static SourcecodeSegment Resolve(Module module, string fileName, byte[] checkSum, int line, int column) { // Do not use ISymUnmanagedReader.GetDocument! It is broken if two files have the same name // Do not use ISymUnmanagedMethod.GetOffset! It sometimes returns negative offset ISymUnmanagedReader symReader = module.SymReader; if (symReader == null) { return(null); // No symbols } ISymUnmanagedDocument symDoc = GetSymDocumentFromFilename(module, fileName, checkSum); if (symDoc == null) { return(null); // Document not found } ISymUnmanagedMethod symMethod; try { uint validLine = symDoc.FindClosestLine((uint)line); symMethod = symReader.GetMethodFromDocumentPosition(symDoc, (uint)validLine, (uint)column); } catch { return(null); //Not found } SequencePoint[] seqPoints = symMethod.GetSequencePoints(); Array.Sort(seqPoints); if (seqPoints.Length == 0) { return(null); } if (line < seqPoints[0].Line) { return(null); } foreach (SequencePoint sqPoint in seqPoints) { if (sqPoint.Line == 0xFEEFEE) { continue; } // If the desired breakpoint position is before the end of the sequence point if (line < sqPoint.EndLine || (line == sqPoint.EndLine && column < sqPoint.EndColumn)) { SourcecodeSegment segment = new SourcecodeSegment(); segment.module = module; segment.filename = symDoc.GetURL(); segment.checkSum = symDoc.GetCheckSum(); segment.startLine = (int)sqPoint.Line; segment.startColumn = (int)sqPoint.Column; segment.endLine = (int)sqPoint.EndLine; segment.endColumn = (int)sqPoint.EndColumn; segment.corFunction = module.CorModule.GetFunctionFromToken(symMethod.GetToken()); segment.ilStart = (int)sqPoint.Offset; segment.ilEnd = (int)sqPoint.Offset; segment.stepRanges = null; return(segment); } } return(null); }
public static void ReplaceSymbolStore(this ISymUnmanagedReader instance, IntPtr filename, IStream pIStream) { instance.__ReplaceSymbolStore(filename, pIStream); }
/// <summary> /// Load symbols for in-memory module /// </summary> public void LoadSymbolsFromMemory(IStream pSymbolStream) { if (this.IsInMemory) { UnloadSymbols(); symReader = metaData.GetSymReader(pSymbolStream); if (symReader != null) { process.TraceMessage("Loaded symbols from memory for " + this.Name); } else { process.TraceMessage("Failed to load symbols from memory"); } OnSymbolsUpdated(); } }
public static void GetDocumentVersion(this ISymUnmanagedReader instance, ISymUnmanagedDocument pDoc, out int version, out int pbCurrent) { instance.__GetDocumentVersion(pDoc, out version, out pbCurrent); }
private ISymUnmanagedReader m_reader; // Unmanaged Reader pointer internal SymReader(ISymUnmanagedReader reader) { m_reader = reader; }
/// <summary> /// Load symblos for on-disk module /// </summary> public void LoadSymbolsFromDisk(IEnumerable<string> symbolsSearchPaths) { if (!IsDynamic && !IsInMemory) { if (symReader == null) { symReader = metaData.GetSymReader(fullPath, string.Join("; ", symbolsSearchPaths ?? new string[0])); if (symReader != null) { process.TraceMessage("Loaded symbols from disk for " + this.Name); OnSymbolsUpdated(); } } } }
public SymbolReaderImpl(ISymUnmanagedReader reader, object[] objsToKeepAlive) { this.reader = reader ?? throw new ArgumentNullException(nameof(reader)); this.objsToKeepAlive = objsToKeepAlive ?? throw new ArgumentNullException(nameof(objsToKeepAlive)); }
/// <summary> /// Load symbols for dynamic module /// (as of .NET 4.0) /// </summary> public void LoadSymbolsDynamic() { if (this.CorModule is ICorDebugModule3 && this.IsDynamic) { Guid guid = new Guid(0, 0, 0, 0xc0, 0, 0, 0, 0, 0, 0, 70); try { symReader = (ISymUnmanagedReader)((ICorDebugModule3)this.CorModule).CreateReaderForInMemorySymbols(guid); } catch (COMException e) { // 0x80131C3B The application did not supply symbols when it loaded or created this module, or they are not yet available. if ((uint)e.ErrorCode == 0x80131C3B) { process.TraceMessage("Failed to load dynamic symbols for " + this.Name); return; } throw; } TrackedComObjects.Track(symReader); process.TraceMessage("Loaded dynamic symbols for " + this.Name); OnSymbolsUpdated(); } }
public unsafe static ModuleInstance Create(ImmutableArray <byte> assemblyImage, ISymUnmanagedReader symReader, bool includeLocalSignatures = true) { // create a new instance of metadata, the resulting object takes an ownership: return(Create(AssemblyMetadata.CreateFromImage(assemblyImage), symReader, includeLocalSignatures)); }
private EditAndContinueMethodDebugInformation GetBaselineEncDebugInfo(MethodDefinitionHandle methodHandle) { Debug.Assert(Thread.CurrentThread.GetApartmentState() == ApartmentState.MTA); if (_pdbReader == null) { // Unmarshal the symbol reader (being marshalled cross thread from STA -> MTA). Debug.Assert(_pdbReaderObjAsStream != IntPtr.Zero); object pdbReaderObjMta; int hr = NativeMethods.GetObjectForStream(_pdbReaderObjAsStream, out pdbReaderObjMta); _pdbReaderObjAsStream = IntPtr.Zero; if (hr != VSConstants.S_OK) { log.Write("Error unmarshaling object from stream."); return default(EditAndContinueMethodDebugInformation); } _pdbReader = (ISymUnmanagedReader)pdbReaderObjMta; } int methodToken = MetadataTokens.GetToken(methodHandle); byte[] debugInfo = _pdbReader.GetCustomDebugInfoBytes(methodToken, methodVersion: 1); if (debugInfo != null) { try { var localSlots = CustomDebugInfoReader.TryGetCustomDebugInfoRecord(debugInfo, CustomDebugInfoKind.EditAndContinueLocalSlotMap); var lambdaMap = CustomDebugInfoReader.TryGetCustomDebugInfoRecord(debugInfo, CustomDebugInfoKind.EditAndContinueLambdaMap); return EditAndContinueMethodDebugInformation.Create(localSlots, lambdaMap); } catch (Exception e) when (e is InvalidOperationException || e is InvalidDataException) { log.Write($"Error reading CDI of method 0x{methodToken:X8}: {e.Message}"); } } return default(EditAndContinueMethodDebugInformation); }
public int GetReaderForFile2( [MarshalAs(UnmanagedType.Interface)] object metadataImport, [MarshalAs(UnmanagedType.LPWStr)] string fileName, [MarshalAs(UnmanagedType.LPWStr)] string searchPath, SymUnmanagedSearchPolicy searchPolicy, [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader reader) { reader = null; try { if (string.IsNullOrEmpty(fileName)) { throw new ArgumentException(null, nameof(fileName)); } var mdImport = MetadataImport.FromObject(metadataImport) ?? throw new ArgumentException(null, nameof(metadataImport)); // See DIA: FLocatePdbDefault, FLocateCvFilePathHelper, FLocatePdbSymsrv, FLocateCvFilePathHelper // // 1) Try open Combine(<PE directory>, <PDB file name>) (unless RestrictReferencePath) // 2) Try open PDB path (unless RestrictOriginalPath) // 3) Search Paths - semicolon separated paths // a) searchPath parameter // b) registry (unless RestrictRegistry) // Use search paths from registry Software\Microsoft\VisualStudio\MSPDB, value SymbolSearchPath // with environment variables expanded (ExpandEnvironmentStrings) // i) try USER // ii) try MACHINE // c) environment vars // i) _NT_ALT_SYMBOL_PATH // ii) _NT_SYMBOL_PATH // ii) SystemRoot (unless RestrictSystemRoot) // // for each search path: // special paths: SRV*<server>, SYMSRV*SYMSRV.DLL*<server> => symbol server (unless RestrictSymsrv) // CACHE*<cache> => sym cache (unless RestrictSymsrv) // // A) try open <path>\symbols\<PE file extension>\<PDB file name> // B) try open <path>\<PE file extension>\<PDB file name> // C) try open <path>\<PDB file name> // // Each attempt checks if PDB ID matches. // // Search policy: all is restricted unless explicitly allowed. // After opened store to cache if CACHE* given (only the first cache?) if (!TryReadCodeViewData(fileName, out var codeViewData, out uint stamp)) { return(HResult.E_FAIL); // TODO: specific error code (ecToHresult)? } Guid guid = codeViewData.Guid; int age = codeViewData.Age; string pdbFileName = Path.GetFileName(codeViewData.Path); var lazyImport = new LazyMetadataImport(mdImport); // 1) next to the PE file if ((searchPolicy & SymUnmanagedSearchPolicy.AllowReferencePathAccess) != 0) { string peDirectory = Path.GetDirectoryName(fileName); string pdbFilePath = Path.Combine(peDirectory, pdbFileName); if (TryCreateReaderForMatchingPdb(pdbFilePath, guid, stamp, age, lazyImport, out reader)) { return(HResult.S_OK); } } // 2) PDB path as specified in Debug Directory if ((searchPolicy & SymUnmanagedSearchPolicy.AllowOriginalPathAccess) != 0) { if (TryCreateReaderForMatchingPdb(codeViewData.Path, guid, stamp, age, lazyImport, out reader)) { return(HResult.S_OK); } } // 3) Search Paths string peFileExtension = Path.GetExtension(fileName).TrimStart('.'); foreach (var searchPaths in GetSearchPathsSequence(searchPath, searchPolicy)) { if (TryFindMatchingPdb(searchPaths, peFileExtension, pdbFileName, guid, stamp, age, lazyImport, searchPolicy, out reader)) { return(HResult.S_OK); } } return(HResult.E_PDB_NOT_FOUND); } finally { InteropUtilities.TransferOwnershipOrRelease(ref metadataImport, reader); } }
public static ImmutableArray <ISymUnmanagedDocument> GetDocuments(this ISymUnmanagedReader reader) { return(ToImmutableOrEmpty(GetItems(reader, (ISymUnmanagedReader a, int b, out int c, ISymUnmanagedDocument[] d) => a.GetDocuments(b, out c, d)))); }
private static ExpressionCompiler.CreateContextDelegate CreateMethodContextFactory( Guid moduleVersionId, ISymUnmanagedReader symReader, int methodToken, int localSignatureToken) { return (blocks, useReferencedModulesOnly) => EvaluationContext.CreateMethodContext( ToCompilation(blocks, useReferencedModulesOnly, moduleVersionId), symReader, moduleVersionId, methodToken, methodVersion: 1, ilOffset: 0, localSignatureToken: localSignatureToken); }
private static int CreateSymbolReader(ISymUnmanagedBinder3 binder, IntPtr importer, string filename, string searchPath, bool avoidLocks, out ISymUnmanagedReader reader) { if (!avoidLocks) { return(binder.GetReaderForFile(importer, filename, searchPath, out reader)); } reader = null; string pdbFilename = Path.ChangeExtension(filename, ".pdb"); if (!File.Exists(pdbFilename)) { return(E_PDB_NOT_FOUND); } try { byte[] bytes = File.ReadAllBytes(pdbFilename); #if USE_ISTREAM IStream stream = new ComStream(new MemoryStream(bytes, 0, bytes.Length, false, true)); return(binder.GetReaderFromStream(importer, stream, out reader)); #else IDiaReadExeAtOffsetCallback callback = new DiaReadExeAtOffsetCallback(bytes); return(binder.GetReaderFromCallback(importer, filename, searchPath, CorSymSearchPolicyAttributes.AllowReferencePathAccess, callback, out reader)); #endif } catch (IOException) { return(E_FAIL); } }
public void Dispose(){ if (this.unmanagedBuffer != null) this.unmanagedBuffer.Dispose(); this.unmanagedBuffer = null; if (this.tables != null) this.tables.Dispose(); //this.tables = null; #if !ROTOR && !UseSingularityPDB if (this.debugReader != null) Marshal.ReleaseComObject(this.debugReader); this.debugReader = null; #endif }