private List <PdbInfo> ReadPdbs() { int offs = _offset; List <PdbInfo> result = new List <PdbInfo>(); var debugData = GetDirectory(DebugDataDirectory); if (debugData.VirtualAddress != 0 && debugData.Size != 0) { if ((debugData.Size % sizeof(IMAGE_DEBUG_DIRECTORY)) != 0) { return(result); } int offset = RvaToOffset((int)debugData.VirtualAddress); if (offset == -1) { return(result); } int count = (int)debugData.Size / sizeof(IMAGE_DEBUG_DIRECTORY); List <Tuple <int, int> > entries = new List <Tuple <int, int> >(count); SeekTo(offset); for (int i = 0; i < count; i++) { IMAGE_DEBUG_DIRECTORY?entryRead = Read <IMAGE_DEBUG_DIRECTORY>(); if (entryRead.HasValue) { IMAGE_DEBUG_DIRECTORY tmp = entryRead.Value; if (tmp.Type == IMAGE_DEBUG_TYPE.CODEVIEW && tmp.SizeOfData >= sizeof(CV_INFO_PDB70)) { entries.Add(Tuple.Create(_virt ? tmp.AddressOfRawData : tmp.PointerToRawData, tmp.SizeOfData)); } } } foreach (Tuple <int, int> tmp in entries.OrderBy(e => e.Item1)) { int ptr = tmp.Item1; int size = tmp.Item2; int?cvSig = Read <int>(ptr); if (cvSig.HasValue && cvSig.Value == CV_INFO_PDB70.PDB70CvSignature) { Guid guid = Read <Guid>() ?? default; int age = Read <int>() ?? -1; // sizeof(sig) + sizeof(guid) + sizeof(age) - [null char] = 0x18 - 1 int nameLen = size - 0x18 - 1; string filename = ReadString(nameLen); PdbInfo pdb = new PdbInfo(filename, guid, age); result.Add(pdb); } } } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="PdbInfoAdapter" /> class. /// </summary> /// <param name="pdbInfo">The PDB information.</param> /// <exception cref="ArgumentNullException">pdbInfo</exception> /// <inheritdoc /> public PdbInfoAdapter(IConverter converter, PdbInfo pdbInfo) : base(converter) { PdbInfo = pdbInfo ?? throw new ArgumentNullException(nameof(pdbInfo)); FileName = PdbInfo.FileName; Guid = PdbInfo.Guid; Revision = PdbInfo.Revision; }
private List <PdbInfo> ReadPdbs() { int offs = _offset; List <PdbInfo> result = new List <PdbInfo>(); var debugData = GetDirectory(DebugDataDirectory); if (debugData.VirtualAddress != 0 && debugData.Size != 0) { if ((debugData.Size % sizeof(IMAGE_DEBUG_DIRECTORY)) != 0) { return(result); } int offset = RvaToOffset((int)debugData.VirtualAddress); if (offset == -1) { return(result); } int count = (int)debugData.Size / sizeof(IMAGE_DEBUG_DIRECTORY); List <Tuple <int, int> > entries = new List <Tuple <int, int> >(count); SeekTo(offset); for (int i = 0; i < count; i++) { if (TryRead(out IMAGE_DEBUG_DIRECTORY directory)) { if (directory.Type == IMAGE_DEBUG_TYPE.CODEVIEW && directory.SizeOfData >= sizeof(CV_INFO_PDB70)) { entries.Add(Tuple.Create(_virt ? directory.AddressOfRawData : directory.PointerToRawData, directory.SizeOfData)); } } } foreach (Tuple <int, int> tmp in entries.OrderBy(e => e.Item1)) { int ptr = tmp.Item1; int size = tmp.Item2; if (TryRead(ptr, out int cvSig) && cvSig == CV_INFO_PDB70.PDB70CvSignature) { Guid guid = Read <Guid>(); int age = Read <int>(); // sizeof(sig) + sizeof(guid) + sizeof(age) - [null char] = 0x18 - 1 int nameLen = size - 0x18 - 1; string?path = ReadString(nameLen); if (path != null) { PdbInfo pdb = new PdbInfo(path, guid, age); result.Add(pdb); } } } } return(result); }
/// <summary> /// Returns information about the PE file. /// </summary> /// <param name="isVirtual">the memory layout of the module</param> /// <param name="address">module base address</param> /// <param name="size">module size</param> /// <param name="pdbInfo">the pdb record or null</param> /// <param name="version">the PE version or null</param> /// <param name="flags">module flags</param> /// <returns>PEImage instance or null</returns> private PEImage GetPEInfo(bool isVirtual, ulong address, ulong size, ref PdbInfo pdbInfo, ref VersionInfo?version, ref Module.Flags flags) { Stream stream = MemoryService.CreateMemoryStream(address, size); try { stream.Position = 0; var peImage = new PEImage(stream, leaveOpen: false, isVirtual); if (peImage.IsValid) { flags |= Module.Flags.IsPEImage; flags |= peImage.IsManaged ? Module.Flags.IsManaged : Module.Flags.None; pdbInfo = peImage.DefaultPdb; if (!version.HasValue) { FileVersionInfo fileVersionInfo = peImage.GetFileVersionInfo(); if (fileVersionInfo != null) { version = fileVersionInfo.VersionInfo; } } flags &= ~(Module.Flags.IsLoadedLayout | Module.Flags.IsFileLayout); flags |= isVirtual ? Module.Flags.IsLoadedLayout : Module.Flags.IsFileLayout; return(peImage); } } catch (Exception ex) when(ex is BadImageFormatException || ex is EndOfStreamException || ex is IOException) { Trace.TraceError($"GetPEInfo: loaded {address:X16} exception {ex.Message}"); } return(null); }
static bool IsMatchingEntry(PdbInfo info, ImageDebugHeaderEntry entry) { if (entry.Directory.Type != ImageDebugType.CodeView) { return(false); } var data = entry.Data; if (data.Length < 24) { return(false); } var magic = ReadInt32(data, 0); if (magic != 0x53445352) { return(false); } var guid_bytes = new byte [16]; Buffer.BlockCopy(data, 4, guid_bytes, 0, 16); return(info.Guid == new Guid(guid_bytes)); }
public NativeModule(NativeRuntime runtime, ModuleInfo module) { _runtime = runtime; _name = string.IsNullOrEmpty(module.FileName) ? "" : Path.GetFileNameWithoutExtension(module.FileName); _filename = module.FileName; _imageBase = module.ImageBase; _size = module.FileSize; _pdb = module.Pdb; }
/// <summary> /// Attempts to locate the pdb for a given module. /// </summary> /// <param name="pdb">The pdb to locate.</param> /// <returns>A full path on disk (local) of where the pdb was copied to.</returns> public string FindPdb(PdbInfo pdb) { if (pdb == null) { throw new ArgumentNullException("pdb"); } return(FindPdb(pdb.FileName, pdb.Guid, pdb.Revision)); }
/// <summary> /// Attempts to locate the pdb for a given module. /// </summary> /// <param name="pdb">The pdb to locate.</param> /// <returns>A full path on disk (local) of where the pdb was copied to.</returns> public async Task <string> FindPdbAsync(PdbInfo pdb) { if (pdb == null) { throw new ArgumentNullException("pdb"); } return(await FindPdbAsync(pdb.FileName, pdb.Guid, pdb.Revision)); }
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); }
public void ManagedPdbTest() { using DataTarget dt = TestTargets.AppDomains.LoadFullDump(); ModuleInfo clrModule = dt.EnumerateModules().SingleOrDefault(m => Path.GetFileNameWithoutExtension(m.FileName).Equals("clr", StringComparison.OrdinalIgnoreCase)); using PEImage img = clrModule.GetPEImage(); Assert.NotNull(img); PdbInfo imgPdb = img.DefaultPdb; Assert.NotNull(imgPdb); Assert.NotNull(imgPdb.Path); }
public void WindowsNativePdbTest() { // Load Windows' ntdll.dll var dllFileName = Path.Combine(Environment.SystemDirectory, "ntdll.dll"); using PEImage img = new PEImage(new FileStream(dllFileName, FileMode.Open, FileAccess.Read)); Assert.NotNull(img); PdbInfo imgPdb = img.DefaultPdb; Assert.NotNull(imgPdb); Assert.NotNull(imgPdb.Path); }
public override int GetHashCode() { int hash = 17; hash = hash * 23 + Version.GetHashCode(); hash = hash * 23 + ImageBase.GetHashCode(); hash = hash * 23 + FilePath.GetHashCode(); hash = hash * 23 + FileName.GetHashCode(); hash = hash * 23 + FileSize.GetHashCode(); hash = hash * 23 + IsManaged.GetHashCode(); hash = hash * 23 + TimeStamp.GetHashCode(); hash = hash * 23 + PdbInfo.GetHashCode(); hash = hash * 23 + Tags.GetHashCode(); return(hash); }
//public static PdbInfo GetPdbInfo(string pdbid, string pdbpath) //{ // if(HFile.Exists(pdbpath) == false) // Pdb.FromPdbid(pdbid, cachepath: pdbpath); // Pdb pdb = Pdb.FromFile(pdbpath); // return GetPdbInfo(pdbid, pdb); //} //static PdbInfo GetPdbInfo(Pdb pdb) //{ // return GetPdbInfo("", pdb); //} static PdbInfo GetPdbInfo(string pdbid, Pdb pdb) { PdbInfo pdbinfo = new PdbInfo { pdbid = pdbid, keywords = pdb.elements.ListType <Pdb.Keywds>().ListKeyword().ToArray(), numAtom = pdb.atoms.Length, numAnisou = pdb.anisous.Length, numModel = pdb.elements.ListType <Pdb.Model>().Count, numChain = pdb.atoms.ListChainID().HListCommonT().Count, numAltloc = pdb.atoms.ListAltLoc().HListCommonT().Count, numResidue = pdb.atoms.ListResSeq().HListCommonT().Count, }; return(pdbinfo); }
/// <summary> /// Attempts to locate the pdb for a given module. /// </summary> /// <param name="module">The module to locate the pdb for.</param> /// <returns>A full path on disk (local) of where the pdb was copied to.</returns> public async Task <string> FindPdbAsync(ModuleInfo module) { if (module == null) { throw new ArgumentNullException("module"); } PdbInfo pdb = module.Pdb; if (pdb == null) { return(null); } return(await FindPdbAsync(pdb)); }
/// <summary> /// Attempts to locate the pdb for a given module. /// </summary> /// <param name="module">The module to locate the pdb for.</param> /// <returns>A full path on disk (local) of where the pdb was copied to.</returns> public string FindPdb(ModuleInfo module) { if (module == null) { throw new ArgumentNullException("module"); } PdbInfo pdb = module.Pdb; if (pdb == null) { return(null); } return(FindPdb(pdb)); }
public void WindowsNativePdbTest() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Load Windows' ntdll.dll var dllFileName = Path.Combine(Environment.SystemDirectory, "ntdll.dll"); using (var winFileStream = new FileStream(dllFileName, FileMode.Open, FileAccess.Read)) { PEImage img = new PEImage(winFileStream); Assert.NotNull(img); PdbInfo imgPdb = img.DefaultPdb; Assert.NotNull(imgPdb); Assert.NotNull(imgPdb.Path); } } }
/// <summary> /// Returns the PE file's PDB info from the debug directory /// </summary> /// <param name="address">module base address</param> /// <param name="size">module size</param> /// <param name="pdbInfo">the pdb record or null</param> /// <param name="version">the PE version or null</param> /// <param name="flags">module flags</param> /// <returns>PEImage instance or null</returns> internal PEImage GetPEInfo(ulong address, ulong size, ref PdbInfo pdbInfo, ref VersionInfo?version, ref Module.Flags flags) { PEImage peImage = null; // None of the modules that lldb (on either Linux/MacOS) provides are PEs if (Target.Host.HostType != HostType.Lldb) { // First try getting the PE info as load layout (native Windows DLLs and most managed PEs on Linux/MacOS). peImage = GetPEInfo(isVirtual: true, address, size, ref pdbInfo, ref version, ref flags); if (peImage == null) { if (Target.OperatingSystem != OSPlatform.Windows) { // Then try getting the PE info as file layout (some managed PEs on Linux/MacOS). peImage = GetPEInfo(isVirtual: false, address, size, ref pdbInfo, ref version, ref flags); } } } return(peImage); }
public static void BuildPdbInfos(Dictionary <string, PdbInfo> pdbinfos) { HDebug.Assert(pdbinfos != null); int countremained = pdbinfos.Count; foreach (string pdbid in pdbinfos.Keys.ToArray()) //Parallel.ForEach(key_pdbids.Keys, delegate(string key) { countremained--; if (pdbinfos[pdbid] != null) { continue; } List <string> pdblines = GetPdbLines(pdbid); if (pdblines == null) { pdblines = GetPdbLines(pdbid, forceToRedownload: true); } HDebug.Assert(pdblines != null); if (pdblines == null) { System.Console.WriteLine(pdbid + " is not processed"); continue; } PdbInfo pdbinfo = GetPdbInfo(pdbid, pdblines); pdbinfos[pdbid] = pdbinfo; System.Console.WriteLine(pdbid + " is processed. There are " + countremained + " unprocessed pdbs."); //Serializer.Serialize(pdbid_pdbinfo_path, pdbid_pdbinfo_VER, pdbid_pdbinfo); } //); }
private static PdbReader GetReaderForFrame(ClrStackFrame frame) { ClrModule module = frame.Method?.Type?.Module; PdbInfo info = module?.Pdb; PdbReader reader = null; if (info != null) { if (!s_pdbReaders.TryGetValue(info, out reader)) { SymbolLocator locator = GetSymbolLocator(module); string pdbPath = locator.FindPdb(info); if (pdbPath != null) { reader = new PdbReader(pdbPath); } s_pdbReaders[info] = reader; } } return(reader); }
private static PdbReader GetReaderForMethod(ClrMethod method) { ClrModule module = method?.Type?.Module; PdbInfo info = module?.Pdb; PdbReader reader = null; if (info != null) { if (!s_pdbReaders.TryGetValue(info, out reader)) { SymbolLocator locator = GetSymbolLocator(module); string pdbPath = locator.FindPdb(info); if (pdbPath != null) { try { reader = new PdbReader(pdbPath); } catch (IOException) { // This will typically happen when trying to load information // from public symbols, or symbol files generated by some weird // compiler. We can ignore this, but there's no need to load // this PDB anymore, so we will put null in the dictionary and // be done with it. reader = null; } } s_pdbReaders[info] = reader; } } return(reader); }
public string FindPdb(PdbInfo pdb) { return(FindPdb(pdb.FileName, pdb.Guid, pdb.Revision)); }
private ClrType ConstructObjectType(ulong eeType) { IMethodTableData mtData = NativeRuntime.GetMethodTableData(eeType); if (mtData == null) { return(null); } ulong componentType = mtData.ElementTypeHandle; bool isArray = componentType != 0; // EEClass is the canonical method table. I stuffed the pointer there instead of creating a new property. ulong canonType = isArray ? componentType : mtData.EEClass; if (!isArray && canonType != 0) { int index; if (!isArray && _indices.TryGetValue(canonType, out index)) { _indices[eeType] = index; // Link the original eeType to its canonical GCHeapType. return(_types[index]); } ulong tmp = eeType; eeType = canonType; canonType = tmp; } NativeModule module = FindContainingModule(eeType); if (module == null && canonType != 0) { module = FindContainingModule(canonType); } string name = null; if (module != null) { Debug.Assert(module.ImageBase < eeType); PdbInfo pdb = module.Pdb; ISymbolResolver resolver; if (pdb != null) { if (!_resolvers.TryGetValue(module, out resolver)) { _resolvers[module] = resolver = _symProvider.GetSymbolResolver(pdb.FileName, pdb.Guid, pdb.Revision); } name = resolver == null ? null : resolver.GetSymbolNameByRVA((uint)(eeType - module.ImageBase)); } } if (name == null) { string moduleName = module != null?Path.GetFileNameWithoutExtension(module.FileName) : "UNKNWON"; name = string.Format("{0}_{1:x}", moduleName, eeType); } int len = name.Length; if (name.EndsWith("::`vftable'")) { len -= 11; } int i = name.IndexOf('!') + 1; name = name.Substring(i, len - i); if (isArray) { name += "[]"; } if (module == null) { module = _mrtModule; } NativeType type = new NativeType(this, _types.Count, module, name, eeType, mtData); _indices[eeType] = _types.Count; if (!isArray) { _indices[canonType] = _types.Count; } _types.Add(type); return(type); }
public static PdbInfo[] GetPdbInfo(params string[] pdbids) { Dictionary <string, PdbInfo> pdbinfos = new Dictionary <string, PdbInfo>(); int VER = 0; string cachepath = RootPath + @"cache\GetPdbInfo.data"; if (HFile.Exists(cachepath)) { HSerialize.Deserialize(cachepath, VER, out pdbinfos); if (pdbinfos == null) { pdbinfos = new Dictionary <string, PdbInfo>(); } } bool updated = false; for (int i = 0; i < pdbids.Length; i++) { string pdbid = pdbids[i]; if (pdbinfos.ContainsKey(pdbid) == false) { pdbinfos.Add(pdbid, null); } if (pdbinfos[pdbid] != null) { continue; } updated = true; //continue; List <string> pdblines = GetPdbLines(pdbid); if (pdblines == null) { pdblines = GetPdbLines(pdbid, forceToRedownload: true); } HDebug.Assert(pdblines != null); if (pdblines == null) { System.Console.WriteLine(pdbid + " is not processed"); continue; } PdbInfo pdbinfo = GetPdbInfo(pdbid, pdblines); pdbinfos[pdbid] = pdbinfo; if (i % 10 == 0) { System.Console.WriteLine(pdbid + " is processed. There are " + (pdbids.Length - i).ToString() + " unprocessed pdbs."); } if (i % 200 == 0) { HSerialize.Serialize(cachepath, VER, pdbinfos); updated = false; System.Console.WriteLine("serialize cache"); } } //GetPdbInfo(pdbinfos); if (updated) { HSerialize.Serialize(cachepath, VER, pdbinfos); } return(pdbinfos.HSelectByKeys(pdbids)); }
public string GetCachedLocation(PdbInfo pdb) { return(Path.Combine(SymbolCache, GetIndexPath(Path.GetFileName(pdb.FileName), pdb.Guid, pdb.Revision))); }