Пример #1
0
        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);
        }
Пример #2
0
 /// <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;
 }
Пример #3
0
        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);
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
        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));
        }
Пример #6
0
 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;
 }
Пример #7
0
        /// <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));
        }
Пример #8
0
 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;
 }
Пример #9
0
        /// <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));
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }
Пример #13
0
        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);
        }
Пример #14
0
        //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);
        }
Пример #15
0
        /// <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));
        }
Пример #16
0
        /// <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));
        }
Пример #17
0
        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);
                }
            }
        }
Пример #18
0
        /// <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);
        }
Пример #19
0
        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);
            }
            //);
        }
Пример #20
0
        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);
        }
Пример #21
0
        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);
        }
Пример #22
0
 public string FindPdb(PdbInfo pdb)
 {
     return(FindPdb(pdb.FileName, pdb.Guid, pdb.Revision));
 }
Пример #23
0
        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);
        }
Пример #24
0
        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));
        }
Пример #25
0
 public string GetCachedLocation(PdbInfo pdb)
 {
     return(Path.Combine(SymbolCache, GetIndexPath(Path.GetFileName(pdb.FileName), pdb.Guid, pdb.Revision)));
 }