public void GetSymbolReader_ReturnsNull_WhenFileNotFound() { var binder = new SymBinder(); var x = SymbolReaderWapper.GetSymbolReader(binder, ""); Assert.IsNull(x); }
public static ISymbolReader CreateReader(string filename) { SymBinder binder = new SymBinder(); object objDispenser, objImporter; CoCreateInstance(ref s_dispenserClassID, null, 1, ref s_dispenserIID, out objDispenser); IMetaDataDispenser dispenser = (IMetaDataDispenser)objDispenser; dispenser.OpenScope(filename, 0, ref s_importerIID, out objImporter); IntPtr importerPtr = IntPtr.Zero; ISymbolReader reader; try { importerPtr = Marshal.GetComInterfaceForObject(objImporter, typeof(IMetadataImport)); reader = binder.GetReader(importerPtr, filename, null); } finally { if (importerPtr != IntPtr.Zero) { Marshal.Release(importerPtr); } } return(reader); }
public static (ImmutableArray <byte> PEImage, ISymUnmanagedReader5 SymReader) EmitAndOpenDummySymReader(Compilation compilation, DebugInformationFormat pdbFormat) { var symBinder = new SymBinder(); var metadataImportProvider = new DummyMetadataImportProvider(); var pdbStream = new MemoryStream(); var peImage = compilation.EmitToArray(new EmitOptions(debugInformationFormat: pdbFormat), pdbStream: pdbStream); pdbStream.Position = 0; var pdbStreamCom = SymUnmanagedStreamFactory.CreateStream(pdbStream); ISymUnmanagedReader5 symReader5; if (pdbFormat == DebugInformationFormat.PortablePdb) { int hr = symBinder.GetReaderFromPdbStream(metadataImportProvider, pdbStreamCom, out var symReader); Assert.Equal(0, hr); symReader5 = (ISymUnmanagedReader5)symReader; } else { symReader5 = SymUnmanagedReaderFactory.CreateReader <ISymUnmanagedReader5>(pdbStream, new DummySymReaderMetadataProvider()); } return(peImage, symReader5); }
public static ISymUnmanagedReader5 OpenDummySymReader(ImmutableArray <byte> pdbImage) { var symBinder = new SymBinder(); var metadataImportProvider = new DummyMetadataImportProvider(); var pdbStream = new MemoryStream(); pdbImage.WriteToStream(pdbStream); var pdbStreamCom = SymUnmanagedStreamFactory.CreateStream(pdbStream); if ( pdbImage.Length > 4 && pdbImage[0] == 'B' && pdbImage[1] == 'S' && pdbImage[2] == 'J' && pdbImage[3] == 'B' ) { var hr = symBinder.GetReaderFromPdbStream( metadataImportProvider, pdbStreamCom, out var symReader ); Assert.Equal(0, hr); return((ISymUnmanagedReader5)symReader); } else { return(SymUnmanagedReaderFactory.CreateReader <ISymUnmanagedReader5>( pdbStream, new DummySymReaderMetadataProvider() )); } }
public static ISymbolReader CreateReader(string filename, byte[] binaryFile) { SymBinder binder = new SymBinder(); object objDispenser, objImporter; CoCreateInstance(ref s_dispenserClassID, null, 1, ref s_dispenserIID, out objDispenser); IntPtr filePtr = Marshal.AllocHGlobal(binaryFile.Length); Marshal.Copy(binaryFile, 0, filePtr, binaryFile.Length); IMetaDataDispenserEx dispenser = (IMetaDataDispenserEx)objDispenser; dispenser.OpenScopeOnMemory(filePtr, (uint)binaryFile.Length, 0, ref s_importerIID, out objImporter); IntPtr importerPtr = IntPtr.Zero; ISymbolReader reader; try { importerPtr = Marshal.GetComInterfaceForObject(objImporter, typeof(IMetadataImport)); reader = binder.GetReader(importerPtr, filename, null); } finally { if (importerPtr != IntPtr.Zero) { Marshal.Release(importerPtr); } } return(reader); }
static IMetaDataDispenser InstantiateDispenser(out SymBinder binder) { binder = new SymBinder(); object dispenser; CoCreateInstance(ref s_dispenserClassID, null, 1, ref s_dispenserIID, out dispenser); return((IMetaDataDispenser)dispenser); }
public void GetSymbolReader_ReturnsNotNull_WhenFileFound() { var location = Path.Combine(Environment.CurrentDirectory, "PartCover.StressTest.exe"); var binder = new SymBinder(); var x = SymbolReaderWapper.GetSymbolReader(binder, location); Assert.IsNotNull(x); }
private string GetLocalVariableName(ulong instructionPointer, uint localIndex) { ClrMethod method = _context.Runtime.GetMethodByAddress(instructionPointer); ClrModule module = method.Type.Module; string pdbLocation = module.TryDownloadPdb(null); IntPtr iunkMetadataImport = Marshal.GetIUnknownForObject(module.MetadataImport); ISymbolReader reader = null; ISymbolMethod symMethod = null; try { using (var binder = new SymBinder()) { reader = binder.GetReader( iunkMetadataImport, module.FileName, Path.GetDirectoryName(pdbLocation)); symMethod = reader.GetMethod(new SymbolToken((int)method.MetadataToken)); return(GetLocalVariableName(symMethod.RootScope, localIndex)); } } catch (COMException comEx) { // E_FAIL occasionally occurs in ISymbolReader.GetMethod. Nothing we can do about it. if ((uint)comEx.HResult == 0x80004005) { return(""); } // 0x806D0005 occurs when the PDB cannot be found or doesn't contain the necessary // information to create a symbol reader. It's OK to ignore. if ((uint)comEx.HResult == 0x806D0005) { return(""); } throw; } finally { // These interfaces aren't IDisposable, but the underlying objects are. And it is // important to dispose of them properly, because if their finalizer runs on exit, // it crashes with an access violation. if (reader != null) { ((IDisposable)reader).Dispose(); } if (symMethod != null) { ((IDisposable)symMethod).Dispose(); } Marshal.Release(iunkMetadataImport); } }
private ISymUnmanagedReader GetReaderForFrame(ClrStackFrame frame) { ClrModule module = frame.Method?.Type?.Module; PdbInfo info = module?.Pdb; ISymUnmanagedReader reader = null; string name = string.Empty; if (info != null) { if (_pdbReaders.TryGetValue(info, out reader)) { return(reader); } name = Path.GetFileName(info.FileName); if (!File.Exists(name)) { _logger?.LogTrace("Symbol file {0} missing", name); return(null); } try { Stream stream = File.OpenRead(name); if (IsPortablePdb(stream)) { var bindar = new SymBinder(); int result = bindar.GetReaderFromPdbFile(new MetaDataImportProvider(module.MetadataImport), name, out reader); } else { reader = SymUnmanagedReaderFactory.CreateReaderWithMetadataImport <ISymUnmanagedReader3>(stream, module.MetadataImport, SymUnmanagedReaderCreationOptions.Default); } } catch (Exception e) { _logger?.LogError(e, "Unable to obtain symbol reader for {0}", name); } } if (reader != null) { _logger?.LogTrace("Symbol file {0} found, reader created", name); _pdbReaders.Add(info, reader); } else { _logger?.LogTrace("Unable to obtain symbol reader for {0}", name); } return(reader); }
private static ISymbolReader TryGetSymbolReaderForFile( SymBinder binder, string pathModule, string searchPath) { ISymbolReader reader; IMetaDataDispenser dispenser = null; IMetaDataImportStub importer = null; var importerPtr = IntPtr.Zero; try { // ReSharper disable once SuspiciousTypeConversion.Global dispenser = (IMetaDataDispenser) new CorMetaDataDispenser(); var importerGuid = new Guid(InterfaceMetaDataImportGuid); importer = (IMetaDataImportStub)dispenser.OpenScope(pathModule, 0, ref importerGuid); // This will manually AddRef the underlying object, so we need to // be very careful to Release it. importerPtr = Marshal.GetComInterfaceForObject(importer, typeof(IMetaDataImportStub)); try { reader = binder.GetReader(importerPtr, pathModule, searchPath); } catch (COMException) { reader = null; } } finally { if (importerPtr != IntPtr.Zero) { Marshal.Release(importerPtr); } if (importer != null) { Marshal.ReleaseComObject(importer); } if (dispenser != null) { Marshal.ReleaseComObject(dispenser); } } return(reader); }
static ISymbolReader InstantiateReader(SymBinder binder, string filename, object objImporter) { IntPtr importerPtr = IntPtr.Zero; ISymbolReader reader; try { importerPtr = Marshal.GetComInterfaceForObject(objImporter, typeof(IMetadataImport)); reader = binder.GetReader(importerPtr, filename, null); } finally { if (importerPtr != IntPtr.Zero) { Marshal.Release(importerPtr); } } return(reader); }
public static DirectoryInfo GetAssemblyCodeBase(Assembly assembly) { var file = new FileInfo(assembly.Location); Guid dispenserClassId = new Guid(DispenserClassId), importerIid = new Guid(ImporterId), dispenserIid = new Guid(DispenserId); object dispenser, importer; CoCreateInstance(ref dispenserClassId, null, 1, ref dispenserIid, out dispenser); ((IMetaDataDispenser)dispenser).OpenScope(file.Name, 0, ref importerIid, out importer); var ptr = Marshal.GetComInterfaceForObject(importer, typeof(IMetaDataImport)); var reader = new SymBinder().GetReader(ptr, file.Name, file.DirectoryName); return(reader.GetDocuments() .Select(d => d.URL) .Where(v => !string.IsNullOrEmpty(v)) .OrderBy(v => v.Length) .Select(v => new FileInfo(v).Directory) .First()); }
/// <summary> /// Updates the symbols for the module given the raw PDB symbol stream. /// </summary> /// <param name="symbolStream">New IStream to use for symbol reading. /// If this is null, unloads the symbols for this module.</param> /// <returns></returns> public bool UpdateSymbols(IStream symbolStream) { if (symbolStream == null) { // Leave m_isSymReaderInitialized so that we don't automatically reload. // MDbgFunction objects cache symbol information. This won't reset that cache. m_isSymReaderInitialized = true; m_symReader = null; return(true); } // Create a new symbol reader for this stream ISymbolReader newSymReader = SymBinder.GetReaderFromStream(Importer.RawCOMObject, symbolStream); if (newSymReader == null) { return(false); } UpdateSymbols(newSymReader); return(true); }
public static ISymbolReader GetSymbolReader(SymBinder binder, string pathModule) { try { object objDispenser; CoCreateInstance(ref CLSID_CorMetaDataDispenser, null, 1, ref IID_IMetaDataDispenser, out objDispenser); object objImporter; IMetaDataDispenser dispenser = (IMetaDataDispenser)objDispenser; dispenser.OpenScope(pathModule, 0, ref IID_IMetaDataImport, out objImporter); IntPtr importerPtr = IntPtr.Zero; ISymbolReader reader; try { importerPtr = Marshal.GetComInterfaceForObject(objImporter, typeof(IMetadataImport)); reader = binder.GetReader(importerPtr, pathModule, null); } finally { if (importerPtr != IntPtr.Zero) { Marshal.Release(importerPtr); } } return(reader); } catch (Exception) { return(null); } }
public static ISymbolReader GetSymReader(this Module module) { object objDispenser; var dispenserClsid = new Guid(0xe5cb7a31, 0x7512, 0x11d2, 0x89, 0xce, 0x00, 0x80, 0xc7, 0x92, 0xe5, 0xd8); // CLSID_CorMetaDataDispenser var dispenserIid = new Guid(0x809c652e, 0x7396, 0x11d2, 0x97, 0x71, 0x00, 0xa0, 0xc9, 0xb4, 0xd5, 0x0c); // IID_IMetaDataDispenser NativeMethods.CoCreateInstance(ref dispenserClsid, null, 1, ref dispenserIid, out objDispenser); var dispenser = (IMetaDataDispenserPrivate)objDispenser; try { object objImporter; var importerIid = new Guid(0x7dac8207, 0xd3ae, 0x4c75, 0x9b, 0x67, 0x92, 0x80, 0x1a, 0x49, 0x7d, 0x44); // IID_IMetaDataImport dispenser.OpenScope(module.Name, 0, ref importerIid, out objImporter); var importerPtr = IntPtr.Zero; ISymbolReader reader; try { importerPtr = Marshal.GetComInterfaceForObject(objImporter, typeof(IMetadataImportPrivateComVisible)); reader = new SymBinder().GetReader(importerPtr, module.Name, null); } finally { if (importerPtr != IntPtr.Zero) { Marshal.Release(importerPtr); } } return(reader); } catch (FileNotFoundException) { return(null); } }
internal static GotoInfo[] LookupLocationsFromPdb(GotoInfo info, IVsSmartOpenScope vsSmartOpenScope) { Debug.Assert(info != null && info.MemberInfo != null, "LookupLocationsFromPdb lacks required parameter"); var sources = new Dictionary <string, Location>(); if (string.IsNullOrEmpty(info.FilePath) || !File.Exists(info.FilePath)) { return(new GotoInfo[0]); } object unkMetaDataImport; IntPtr ptrMetaDataImport = IntPtr.Zero; ISymbolBinder1 binder; ISymbolReader reader; ISymbolDocument[] documents; int[] lines; int[] columns; int[] endLines; int[] endColumns; int[] offsets; var methods = new List <MethodBase>(); Type ty = null; try { int hr = vsSmartOpenScope.OpenScope(info.FilePath, 0, ref IID_MetaDataImport, out unkMetaDataImport); if (hr == VSConstants.S_OK) { ptrMetaDataImport = Marshal.GetIUnknownForObject(unkMetaDataImport); binder = new SymBinder(); reader = binder.GetReader(ptrMetaDataImport, info.FilePath, null); documents = new ISymbolDocument[1]; lines = new int[1]; columns = new int[1]; endLines = new int[1]; endColumns = new int[1]; offsets = new int[1]; } else { Debug.WriteLineIf(TS.TraceWarning, string.Format("Failed to obtain MetaDataImport from VS, hr 0x{0:X8}", hr), TS.DisplayName); return(new GotoInfo[0]); } switch (info.MemberInfo.MemberType) { case MemberTypes.Constructor: case MemberTypes.Method: MethodBase mb = (MethodBase)info.MemberInfo; // Abstract methods does not contain any code. // if (mb.IsAbstract) { methods.AddRange(mb.DeclaringType.GetMethods(DeclaredMembers)); } else { methods.Add(mb); } break; case MemberTypes.Property: PropertyInfo pi = (PropertyInfo)info.MemberInfo; methods.AddRange(pi.GetAccessors(true)); break; case MemberTypes.Field: methods.AddRange(info.MemberInfo.DeclaringType.GetMethods(DeclaredMembers)); break; case MemberTypes.Event: EventInfo ei = (EventInfo)info.MemberInfo; methods.Add(ei.GetAddMethod(true)); methods.Add(ei.GetRemoveMethod(true)); methods.Add(ei.GetRaiseMethod(true)); methods.AddRange(ei.GetOtherMethods(true)); break; case MemberTypes.TypeInfo: case MemberTypes.NestedType: ty = (Type)info.MemberInfo; methods.AddRange(ty.GetMethods(DeclaredMembers)); methods.AddRange(ty.GetConstructors(DeclaredMembers)); break; default: Trace.Fail("Unexpected MemberType " + info.MemberInfo.MemberType); break; } foreach (MethodBase mb in methods) { if (mb == null || Attribute.GetCustomAttribute(mb, typeof(CompilerGeneratedAttribute)) != null) { continue; } try { SymbolToken token = new SymbolToken(mb.MetadataToken); ISymbolMethod method = reader.GetMethod(token); if (method.SequencePointCount > 0) { method.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns); var path = documents[0].URL; // We are interested in unique files only. if (File.Exists(path) && (ty == null || mb.DeclaringType.Equals(ty))) { Location value; if (sources.TryGetValue(path, out value)) { if ((value.Column == 0 || value.Line == 0) && lines[0] != 0 && columns[0] != 0) { sources[path] = new Location(path, lines[0], columns[0], endLines[0], endColumns[0]); } } else { sources.Add(path, new Location(path, lines[0], columns[0], endLines[0], endColumns[0])); } } } } catch (COMException ex) { // Abstract method or not a method at all. // Sequence points are available only for methods. // Trace.WriteLineIf(TS.TraceError, string.Format("({0}) {1}, code 0x{2:X8}", mb.Name, ex.Message, ex.ErrorCode), TS.DisplayName); } } } catch (COMException ex) { // The file was not found or source locations were stripped from the pdb. // Trace.WriteLineIf(TS.TraceError, string.Format("{0}, code 0x{1:8X}", ex.Message, ex.ErrorCode), TS.DisplayName); } finally { if (ptrMetaDataImport != IntPtr.Zero) { Marshal.Release(ptrMetaDataImport); } } return(sources.Select(x => new GotoInfo(x.Key, x.Value)).ToArray()); }
public void DebugInfo(DebugInformationFormat format) { var symBinder = new SymBinder(); var metadataImportProvider = new DummyMetadataImportProvider(); var source = @" using System; delegate void D(); class C { public static void Main() { int x = 1; D d = () => Console.Write(x); d(); } } "; var compilation = CSharpTestBase.CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll); var pdbStream = new MemoryStream(); compilation.EmitToArray(new EmitOptions(debugInformationFormat: format), pdbStream: pdbStream); pdbStream.Position = 0; var pdbStreamCom = SymUnmanagedStreamFactory.CreateStream(pdbStream); ISymUnmanagedReader5 symReader5; if (format == DebugInformationFormat.PortablePdb) { int hr = symBinder.GetReaderFromPdbStream(metadataImportProvider, pdbStreamCom, out var symReader); Assert.Equal(0, hr); symReader5 = (ISymUnmanagedReader5)symReader; } else { symReader5 = SymUnmanagedReaderFactory.CreateReader <ISymUnmanagedReader5>(pdbStream, new DummySymReaderMetadataProvider()); } var reader = EditAndContinueMethodDebugInfoReader.Create(symReader5, version: 1); // Main method var debugInfo = reader.GetDebugInfo(MetadataTokens.MethodDefinitionHandle(5)); Assert.Equal(0, debugInfo.GetMethodOrdinal()); AssertEx.Equal(new[] { "Offset=0 Ordinal=0 Kind=LambdaDisplayClass", "Offset=33 Ordinal=0 Kind=UserDefined" }, debugInfo.InspectLocalSlots()); AssertEx.Equal(new[] { "Offset=43 Id=0#0 Closure=0" }, debugInfo.InspectLambdas()); AssertEx.Equal(new[] { "Offset=0 Id=0#0" }, debugInfo.InspectClosures()); var localSig = reader.GetLocalSignature(MetadataTokens.MethodDefinitionHandle(5)); Assert.Equal(MetadataTokens.StandaloneSignatureHandle(1), localSig); // method without debug information: debugInfo = reader.GetDebugInfo(MetadataTokens.MethodDefinitionHandle(1)); Assert.Equal(-1, debugInfo.GetMethodOrdinal()); Assert.Null(debugInfo.InspectLocalSlots()); Assert.Null(debugInfo.InspectLambdas()); Assert.Null(debugInfo.InspectClosures()); localSig = reader.GetLocalSignature(MetadataTokens.MethodDefinitionHandle(1)); Assert.Equal(default, localSig);
public SymbolReaderFactory() { _symBinder = new SymBinder(); }