예제 #1
0
        private ImmutableArray <byte> GetMetaDataFromAssembly(ClrModule module)
        {
            Debug.Assert(module.ImageBase != 0);

            var  metadata  = ImmutableArray <byte> .Empty;
            bool isVirtual = module.Layout != ModuleLayout.Flat;

            try
            {
                Stream stream = _memoryService.CreateMemoryStream(module.ImageBase, module.Size > 0 ? module.Size : 4096);
                PEFile peFile = new(new StreamAddressSpace(stream), isVirtual);
                if (peFile.IsValid())
                {
                    metadata = SymbolService.GetMetadata(module.Name, peFile.Timestamp, peFile.SizeOfImage);
                }
                else
                {
                    Trace.TraceError($"GetMetaData: {module.ImageBase:X16} not valid PE");
                }
            }
            catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException)
            {
                Trace.TraceError($"GetMetaData: loaded {module.ImageBase:X16} exception {ex.Message}");
            }
            return(metadata);
        }
        private ImmutableArray <byte> GetMetaDataFromAssembly(ClrModule module)
        {
            Debug.Assert(module.ImageBase != 0);

            var  metadata  = ImmutableArray <byte> .Empty;
            bool isVirtual = module.Layout != ModuleLayout.Flat;

            try
            {
                ulong size = module.Size;
                if (size == 0)
                {
                    size = 4096;
                }
                Stream stream  = _memoryService.CreateMemoryStream(module.ImageBase, size);
                var    peImage = new PEImage(stream, leaveOpen: false, isVirtual);
                if (peImage.IsValid)
                {
                    metadata = SymbolService.GetMetadata(module.Name, (uint)peImage.IndexTimeStamp, (uint)peImage.IndexFileSize);
                }
                else
                {
                    Trace.TraceError($"GetMetaData: {module.ImageBase:X16} not valid PE");
                }
            }
            catch (Exception ex) when(ex is BadImageFormatException || ex is EndOfStreamException || ex is IOException)
            {
                Trace.TraceError($"GetMetaData: loaded {module.ImageBase:X16} exception {ex.Message}");
            }
            return(metadata);
        }
예제 #3
0
 /// <summary>
 /// Returns method token and IL offset for given source line number.
 /// </summary>
 /// <param name="filePath">source file name and path</param>
 /// <param name="lineNumber">source line number</param>
 /// <param name="methodToken">method token return</param>
 /// <param name="ilOffset">IL offset return</param>
 /// <returns>true if information is available</returns>
 public bool ResolveSequencePoint(
     string filePath,
     int lineNumber,
     out int methodToken,
     out int ilOffset)
 {
     methodToken = 0;
     ilOffset    = 0;
     try
     {
         string fileName = SymbolService.GetFileName(filePath);
         foreach (MethodDebugInformationHandle methodDebugInformationHandle in _reader.MethodDebugInformation)
         {
             MethodDebugInformation  methodDebugInfo = _reader.GetMethodDebugInformation(methodDebugInformationHandle);
             SequencePointCollection sequencePoints  = methodDebugInfo.GetSequencePoints();
             foreach (SequencePoint point in sequencePoints)
             {
                 string sourceName = _reader.GetString(_reader.GetDocument(point.Document).Name);
                 if (point.StartLine == lineNumber && SymbolService.GetFileName(sourceName) == fileName)
                 {
                     methodToken = MetadataTokens.GetToken(methodDebugInformationHandle.ToDefinitionHandle());
                     ilOffset    = point.Offset;
                     return(true);
                 }
             }
         }
     }
     catch (Exception ex)
     {
         Trace.TraceError($"ResolveSequencePoint: {ex.Message}");
     }
     return(false);
 }
예제 #4
0
        private string DownloadFile(string fileName)
        {
            OSPlatform platform = _target.OperatingSystem;
            string     filePath = null;

            if (SymbolService.IsSymbolStoreEnabled)
            {
                SymbolStoreKey key = null;

                if (platform == OSPlatform.OSX)
                {
                    KeyGenerator generator = MemoryService.GetKeyGenerator(
                        platform,
                        RuntimeModule.FileName,
                        RuntimeModule.ImageBase,
                        RuntimeModule.ImageSize);

                    key = generator.GetKeys(KeyTypeFlags.DacDbiKeys).SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == fileName);
                }
                else if (platform == OSPlatform.Linux)
                {
                    if (!RuntimeModule.BuildId.IsDefaultOrEmpty)
                    {
                        IEnumerable <SymbolStoreKey> keys = ELFFileKeyGenerator.GetKeys(
                            KeyTypeFlags.DacDbiKeys,
                            RuntimeModule.FileName,
                            RuntimeModule.BuildId.ToArray(),
                            symbolFile: false,
                            symbolFileName: null);

                        key = keys.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == fileName);
                    }
                }
                else if (platform == OSPlatform.Windows)
                {
                    if (RuntimeModule.IndexTimeStamp.HasValue && RuntimeModule.IndexFileSize.HasValue)
                    {
                        // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
                        key = PEFileKeyGenerator.GetKey(fileName, RuntimeModule.IndexTimeStamp.Value, RuntimeModule.IndexFileSize.Value);
                    }
                }

                if (key != null)
                {
                    // Now download the DAC module from the symbol server
                    filePath = SymbolService.DownloadFile(key);
                }
                else
                {
                    Trace.TraceInformation($"DownloadFile: {fileName}: key not generated");
                }
            }
            else
            {
                Trace.TraceInformation($"DownLoadFile: {fileName}: symbol store not enabled");
            }
            return(filePath);
        }
예제 #5
0
        /// <summary>
        /// Finds or downloads the ELF module and creates a MachOFile instance for it.
        /// </summary>
        /// <param name="module">module instance</param>
        /// <returns>MachO file instance or null</returns>
        internal MachOFile GetMachOFile(IModule module)
        {
            string    downloadFilePath = null;
            MachOFile machoFile        = null;

            if (File.Exists(module.FileName))
            {
                // TODO - Need to verify the build id matches this local file
                downloadFilePath = module.FileName;
            }
            else
            {
                if (SymbolService.IsSymbolStoreEnabled)
                {
                    if (!module.BuildId.IsDefaultOrEmpty)
                    {
                        var key = MachOFileKeyGenerator.GetKeys(KeyTypeFlags.IdentityKey, module.FileName, module.BuildId.ToArray(), symbolFile: false, symbolFileName: null).SingleOrDefault();
                        if (key != null)
                        {
                            // Now download the module from the symbol server
                            downloadFilePath = SymbolService.DownloadFile(key);
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(downloadFilePath))
            {
                Trace.TraceInformation("GetMachOFile: downloaded {0}", downloadFilePath);
                Stream stream;
                try
                {
                    stream = File.OpenRead(downloadFilePath);
                }
                catch (Exception ex) when(ex is DirectoryNotFoundException || ex is FileNotFoundException || ex is UnauthorizedAccessException || ex is IOException)
                {
                    Trace.TraceError($"GetMachOFile: OpenRead exception {ex.Message}");
                    return(null);
                }
                try
                {
                    machoFile = new MachOFile(new StreamAddressSpace(stream), position: 0, dataSourceIsVirtualAddressSpace: false);
                    if (!machoFile.IsValid())
                    {
                        return(null);
                    }
                }
                catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException)
                {
                    Trace.TraceError($"GetMachOFile: exception {ex.Message}");
                    return(null);
                }
            }

            return(machoFile);
        }
예제 #6
0
        /// <summary>
        /// Finds or downloads the module and creates a PEReader for it.
        /// </summary>
        /// <param name="module">module instance</param>
        /// <returns>reader or null</returns>
        internal PEReader GetPEReader(IModule module)
        {
            string   downloadFilePath = null;
            PEReader reader           = null;

            if (File.Exists(module.FileName))
            {
                // TODO - Need to verify the index timestamp/file size matches this local file
                downloadFilePath = module.FileName;
            }
            else
            {
                if (SymbolService.IsSymbolStoreEnabled)
                {
                    if (module.IndexTimeStamp.HasValue && module.IndexFileSize.HasValue)
                    {
                        SymbolStoreKey key = PEFileKeyGenerator.GetKey(Path.GetFileName(module.FileName), module.IndexTimeStamp.Value, module.IndexFileSize.Value);
                        if (key != null)
                        {
                            // Now download the module from the symbol server
                            downloadFilePath = SymbolService.DownloadFile(key);
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(downloadFilePath))
            {
                Trace.TraceInformation("GetPEReader: downloaded {0}", downloadFilePath);
                Stream stream;
                try
                {
                    stream = File.OpenRead(downloadFilePath);
                }
                catch (Exception ex) when(ex is DirectoryNotFoundException || ex is FileNotFoundException || ex is UnauthorizedAccessException || ex is IOException)
                {
                    Trace.TraceError($"GetPEReader: OpenRead exception {ex.Message}");
                    return(null);
                }
                try
                {
                    reader = new PEReader(stream);
                    if (reader.PEHeaders == null || reader.PEHeaders.PEHeader == null)
                    {
                        return(null);
                    }
                }
                catch (Exception ex) when(ex is BadImageFormatException || ex is IOException)
                {
                    Trace.TraceError($"GetPEReader: PEReader exception {ex.Message}");
                    return(null);
                }
            }

            return(reader);
        }
예제 #7
0
        /// <summary>
        /// Finds or downloads the module and creates a PEReader for it.
        /// </summary>
        /// <param name="module">module instance</param>
        /// <returns>reader or null</returns>
        internal PEReader GetPEReader(IModule module)
        {
            if (!module.IndexTimeStamp.HasValue || !module.IndexFileSize.HasValue)
            {
                Trace.TraceWarning($"GetPEReader: module {module.FileName} has no index timestamp/filesize");
                return(null);
            }

            SymbolStoreKey moduleKey = PEFileKeyGenerator.GetKey(Path.GetFileName(module.FileName), module.IndexTimeStamp.Value, module.IndexFileSize.Value);

            if (moduleKey is null)
            {
                Trace.TraceWarning($"GetPEReader: no index generated for module {module.FileName} ");
                return(null);
            }

            if (File.Exists(module.FileName))
            {
                Stream stream = OpenFile(module.FileName);
                if (stream is not null)
                {
                    var peFile    = new PEFile(new StreamAddressSpace(stream), false);
                    var generator = new PEFileKeyGenerator(Tracer.Instance, peFile, module.FileName);
                    IEnumerable <SymbolStoreKey> keys = generator.GetKeys(KeyTypeFlags.IdentityKey);
                    foreach (SymbolStoreKey key in keys)
                    {
                        if (moduleKey.Equals(key))
                        {
                            Trace.TraceInformation("GetPEReader: local file match {0}", module.FileName);
                            return(OpenPEReader(module.FileName));
                        }
                    }
                }
            }

            // Now download the module from the symbol server if local file doesn't exists or doesn't have the right key
            string downloadFilePath = SymbolService.DownloadFile(moduleKey);

            if (!string.IsNullOrEmpty(downloadFilePath))
            {
                Trace.TraceInformation("GetPEReader: downloaded {0}", downloadFilePath);
                return(OpenPEReader(downloadFilePath));
            }

            return(null);
        }
예제 #8
0
        /// <summary>
        /// Finds or downloads the ELF module and creates a MachOFile instance for it.
        /// </summary>
        /// <param name="module">module instance</param>
        /// <returns>MachO file instance or null</returns>
        internal MachOFile GetMachOFile(IModule module)
        {
            if (module.BuildId.IsDefaultOrEmpty)
            {
                Trace.TraceWarning($"GetMachOFile: module {module.FileName} has no build id");
                return(null);
            }

            SymbolStoreKey moduleKey = MachOFileKeyGenerator.GetKeys(KeyTypeFlags.IdentityKey, module.FileName, module.BuildId.ToArray(), symbolFile: false, symbolFileName: null).SingleOrDefault();

            if (moduleKey is null)
            {
                Trace.TraceWarning($"GetMachOFile: no index generated for module {module.FileName} ");
                return(null);
            }

            if (File.Exists(module.FileName))
            {
                MachOFile machOFile = OpenMachOFile(module.FileName);
                if (machOFile is not null)
                {
                    var generator = new MachOFileKeyGenerator(Tracer.Instance, machOFile, module.FileName);
                    IEnumerable <SymbolStoreKey> keys = generator.GetKeys(KeyTypeFlags.IdentityKey);
                    foreach (SymbolStoreKey key in keys)
                    {
                        if (moduleKey.Equals(key))
                        {
                            Trace.TraceInformation("GetMachOFile: local file match {0}", module.FileName);
                            return(machOFile);
                        }
                    }
                }
            }

            // Now download the module from the symbol server if local file doesn't exists or doesn't have the right key
            string downloadFilePath = SymbolService.DownloadFile(moduleKey);

            if (!string.IsNullOrEmpty(downloadFilePath))
            {
                Trace.TraceInformation("GetMachOFile: downloaded {0}", downloadFilePath);
                return(OpenMachOFile(downloadFilePath));
            }

            return(null);
        }
예제 #9
0
        private string DownloadFile(string fileName)
        {
            OSPlatform platform = _target.OperatingSystem;
            string     filePath = null;

            if (SymbolService.IsSymbolStoreEnabled)
            {
                SymbolStoreKey key = null;

                if (platform == OSPlatform.Windows)
                {
                    // It is the coreclr.dll's id (timestamp/filesize) in the DacInfo used to download the the dac module.
                    if (_clrInfo.DacInfo.IndexTimeStamp != 0 && _clrInfo.DacInfo.IndexFileSize != 0)
                    {
                        key = PEFileKeyGenerator.GetKey(fileName, (uint)_clrInfo.DacInfo.IndexTimeStamp, (uint)_clrInfo.DacInfo.IndexFileSize);
                    }
                    else
                    {
                        Trace.TraceError($"DownloadFile: {fileName}: key not generated - no index timestamp/filesize");
                    }
                }
                else
                {
                    // Use the runtime's build id to download the the dac module.
                    if (!_clrInfo.DacInfo.ClrBuildId.IsDefaultOrEmpty)
                    {
                        byte[] buildId = _clrInfo.DacInfo.ClrBuildId.ToArray();
                        IEnumerable <SymbolStoreKey> keys = null;

                        if (platform == OSPlatform.Linux)
                        {
                            keys = ELFFileKeyGenerator.GetKeys(KeyTypeFlags.DacDbiKeys, "libcoreclr.so", buildId, symbolFile: false, symbolFileName: null);
                        }
                        else if (platform == OSPlatform.OSX)
                        {
                            keys = MachOFileKeyGenerator.GetKeys(KeyTypeFlags.DacDbiKeys, "libcoreclr.dylib", buildId, symbolFile: false, symbolFileName: null);
                        }
                        else
                        {
                            Trace.TraceError($"DownloadFile: {fileName}: platform not supported - {platform}");
                        }

                        key = keys?.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == fileName);
                    }
                    else
                    {
                        Trace.TraceError($"DownloadFile: {fileName}: key not generated - no index time stamp or file size");
                    }
                }

                if (key is not null)
                {
                    // Now download the DAC module from the symbol server
                    filePath = SymbolService.DownloadFile(key);
                }
            }
            else
            {
                Trace.TraceInformation($"DownLoadFile: {fileName}: symbol store not enabled");
            }
            return(filePath);
        }