Пример #1
0
        protected override async Task <SymbolStoreFile> GetFileInner(SymbolStoreKey key, CancellationToken token)
        {
            Uri uri = GetRequestUri(key.Index);

            bool needsChecksumMatch = key.PdbChecksums.Any();

            if (needsChecksumMatch)
            {
                string     checksumHeader = string.Join(";", key.PdbChecksums);
                HttpClient client         = _authenticatedClient ?? _client;
                Tracer.Information($"SymbolChecksum: {checksumHeader}");
                client.DefaultRequestHeaders.Add("SymbolChecksum", checksumHeader);
            }

            Stream stream = await GetFileStream(uri, token);

            if (stream != null)
            {
                if (needsChecksumMatch)
                {
                    ChecksumValidator.Validate(Tracer, stream, key.PdbChecksums);
                }
                return(new SymbolStoreFile(stream, uri.ToString()));
            }
            return(null);
        }
Пример #2
0
 /// <summary>
 /// Returns the metadata for the assembly
 /// </summary>
 /// <param name="imagePath">file name and path to module</param>
 /// <param name="imageTimestamp">module timestamp</param>
 /// <param name="imageSize">size of PE image</param>
 /// <returns>metadata</returns>
 public ImmutableArray <byte> GetMetadata(string imagePath, uint imageTimestamp, uint imageSize)
 {
     try
     {
         Stream peStream = null;
         if (imagePath != null && File.Exists(imagePath))
         {
             peStream = Utilities.TryOpenFile(imagePath);
         }
         else if (IsSymbolStoreEnabled)
         {
             SymbolStoreKey key = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
             peStream = GetSymbolStoreFile(key)?.Stream;
         }
         if (peStream != null)
         {
             using var peReader = new PEReader(peStream, PEStreamOptions.Default);
             if (peReader.HasMetadata)
             {
                 PEMemoryBlock metadataInfo = peReader.GetMetadata();
                 return(metadataInfo.GetContent());
             }
         }
     }
     catch (Exception ex) when
         (ex is UnauthorizedAccessException ||
         ex is BadImageFormatException ||
         ex is InvalidVirtualAddressException ||
         ex is IOException)
     {
         Trace.TraceError($"GetMetaData: {ex.Message}");
     }
     return(ImmutableArray <byte> .Empty);
 }
Пример #3
0
        public override IEnumerable <SymbolStoreKey> GetKeys(KeyTypeFlags flags)
        {
            if ((flags & KeyTypeFlags.IdentityKey) != 0)
            {
                SymbolStoreKey key = null;

                try
                {
                    _file.Stream.Position = 0;
                    using (MetadataReaderProvider provider = MetadataReaderProvider.FromPortablePdbStream(_file.Stream, MetadataStreamOptions.LeaveOpen))
                    {
                        MetadataReader reader = provider.GetMetadataReader();
                        var            blob   = new BlobContentId(reader.DebugMetadataHeader.Id);
                        if ((flags & KeyTypeFlags.ForceWindowsPdbs) == 0)
                        {
                            key = GetKey(_file.FileName, blob.Guid);
                        }
                        else
                        {
                            // Force the Windows PDB index
                            key = PDBFileKeyGenerator.GetKey(_file.FileName, blob.Guid, 1);
                        }
                    }
                }
                catch (BadImageFormatException ex)
                {
                    Tracer.Warning("PortablePDBFileKeyGenerator {0}", ex.Message);
                }

                if (key != null)
                {
                    yield return(key);
                }
            }
        }
Пример #4
0
        internal async Task DownloadFiles()
        {
            using (SymbolStore symbolStore = BuildSymbolStore())
            {
                bool verifyPackages = Packages && OutputDirectory == null;

                KeyTypeFlags flags = KeyTypeFlags.None;
                if (Symbols)
                {
                    flags |= KeyTypeFlags.SymbolKey;
                }
                if (Modules)
                {
                    flags |= KeyTypeFlags.IdentityKey;
                }
                if (Debugging)
                {
                    flags |= KeyTypeFlags.ClrKeys;
                }
                if (flags == KeyTypeFlags.None)
                {
                    if (verifyPackages)
                    {
                        // If we are verifing symbol packages then only check the identity and clr keys.
                        flags = KeyTypeFlags.IdentityKey | KeyTypeFlags.ClrKeys;
                    }
                    else
                    {
                        // The default is to download everything
                        flags = KeyTypeFlags.IdentityKey | KeyTypeFlags.SymbolKey | KeyTypeFlags.ClrKeys;
                    }
                }
                if (ForceWindowsPdbs)
                {
                    flags |= KeyTypeFlags.ForceWindowsPdbs;
                }

                foreach (SymbolStoreKeyWrapper wrapper in GetKeys(flags).Distinct())
                {
                    SymbolStoreKey key = wrapper.Key;
                    Tracer.Information("Key: {0} - {1}{2}", key.Index, key.FullPathName, key.IsClrSpecialFile ? "*" : "");

                    if (symbolStore != null)
                    {
                        using (SymbolStoreFile symbolFile = await symbolStore.GetFile(key, CancellationToken.None))
                        {
                            if (symbolFile != null)
                            {
                                await WriteFile(symbolFile, wrapper);
                            }
                            // If there is no output directory verify the file exists in the symbol store
                            if (OutputDirectory == null)
                            {
                                Tracer.WriteLine("Key {0}found {1} - {2}", symbolFile != null ? "" : "NOT ", key.Index, key.FullPathName);
                            }
                        }
                    }
                }
            }
        }
Пример #5
0
 internal async Task DownloadFiles(bool symbolsOnly, bool forceWindowsPdbs)
 {
     using (SymbolStore symbolStore = BuildSymbolStore())
     {
         KeyTypeFlags flags;
         if (symbolsOnly)
         {
             flags = KeyTypeFlags.SymbolKey;
         }
         else
         {
             flags = KeyTypeFlags.IdentityKey | KeyTypeFlags.SymbolKey | KeyTypeFlags.ClrKeys;
         }
         if (forceWindowsPdbs)
         {
             flags |= KeyTypeFlags.ForceWindowsPdbs;
         }
         foreach (SymbolStoreKeyWrapper wrapper in GetKeys(flags).Distinct())
         {
             SymbolStoreKey key = wrapper.Key;
             if (symbolStore != null)
             {
                 using (SymbolStoreFile symbolFile = await symbolStore.GetFile(key, CancellationToken.None))
                 {
                     if (symbolFile != null)
                     {
                         await WriteFile(symbolFile, wrapper);
                     }
                 }
             }
         }
     }
 }
Пример #6
0
        /// <summary>
        /// Load native modules (i.e. DAC, DBI) from the runtime build id.
        /// </summary>
        /// <param name="callback">called back for each symbol file loaded</param>
        /// <param name="parameter">callback parameter</param>
        /// <param name="config">Target configuration: Windows, Linux or OSX</param>
        /// <param name="moduleFilePath">module path</param>
        /// <param name="specialKeys">if true, returns the DBI/DAC keys, otherwise the identity key</param>
        /// <param name="moduleIndexSize">build id size</param>
        /// <param name="moduleIndex">pointer to build id</param>
        private void LoadNativeSymbolsFromIndex(
            IntPtr self,
            SymbolFileCallback callback,
            IntPtr parameter,
            RuntimeConfiguration config,
            string moduleFilePath,
            bool specialKeys,
            int moduleIndexSize,
            IntPtr moduleIndex)
        {
            if (_symbolService.IsSymbolStoreEnabled)
            {
                try
                {
                    KeyTypeFlags flags = specialKeys ? KeyTypeFlags.DacDbiKeys : KeyTypeFlags.IdentityKey;
                    byte[]       id    = new byte[moduleIndexSize];
                    Marshal.Copy(moduleIndex, id, 0, moduleIndexSize);

                    IEnumerable <SymbolStoreKey> keys = null;
                    switch (config)
                    {
                    case RuntimeConfiguration.UnixCore:
                        keys = ELFFileKeyGenerator.GetKeys(flags, moduleFilePath, id, symbolFile: false, symbolFileName: null);
                        break;

                    case RuntimeConfiguration.OSXCore:
                        keys = MachOFileKeyGenerator.GetKeys(flags, moduleFilePath, id, symbolFile: false, symbolFileName: null);
                        break;

                    case RuntimeConfiguration.WindowsCore:
                    case RuntimeConfiguration.WindowsDesktop:
                        uint           timeStamp = BitConverter.ToUInt32(id, 0);
                        uint           fileSize  = BitConverter.ToUInt32(id, 4);
                        SymbolStoreKey key       = PEFileKeyGenerator.GetKey(moduleFilePath, timeStamp, fileSize);
                        keys = new SymbolStoreKey[] { key };
                        break;

                    default:
                        Trace.TraceError("LoadNativeSymbolsFromIndex: unsupported platform {0}", config);
                        return;
                    }
                    foreach (SymbolStoreKey key in keys)
                    {
                        string moduleFileName = Path.GetFileName(key.FullPathName);
                        Trace.TraceInformation("{0} {1}", key.FullPathName, key.Index);

                        string downloadFilePath = _symbolService.DownloadFile(key);
                        if (downloadFilePath != null)
                        {
                            Trace.TraceInformation("{0}: {1}", moduleFileName, downloadFilePath);
                            callback(parameter, moduleFileName, downloadFilePath);
                        }
                    }
                }
                catch (Exception ex) when(ex is BadInputFormatException || ex is InvalidVirtualAddressException || ex is TaskCanceledException)
                {
                    Trace.TraceError("{0} - {1}", ex.Message, moduleFilePath);
                }
            }
        }
Пример #7
0
        private string GetDacFile(ClrInfo clrInfo)
        {
            if (_dacFilePath == null)
            {
                Debug.Assert(!string.IsNullOrEmpty(clrInfo.DacInfo.FileName));
                var    analyzeContext = _serviceProvider.GetService <AnalyzeContext>();
                string dacFilePath    = null;
                if (!string.IsNullOrEmpty(analyzeContext.RuntimeModuleDirectory))
                {
                    dacFilePath = Path.Combine(analyzeContext.RuntimeModuleDirectory, clrInfo.DacInfo.FileName);
                    if (File.Exists(dacFilePath))
                    {
                        _dacFilePath = dacFilePath;
                    }
                }
                if (_dacFilePath == null)
                {
                    dacFilePath = clrInfo.LocalMatchingDac;
                    if (!string.IsNullOrEmpty(dacFilePath) && File.Exists(dacFilePath))
                    {
                        _dacFilePath = dacFilePath;
                    }
                    else if (SymbolReader.IsSymbolStoreEnabled())
                    {
                        string dacFileName = Path.GetFileName(dacFilePath ?? clrInfo.DacInfo.FileName);
                        if (dacFileName != null)
                        {
                            SymbolStoreKey key = null;

                            if (clrInfo.ModuleInfo.BuildId != null)
                            {
                                IEnumerable <SymbolStoreKey> keys = ELFFileKeyGenerator.GetKeys(
                                    KeyTypeFlags.DacDbiKeys, clrInfo.ModuleInfo.FileName, clrInfo.ModuleInfo.BuildId, symbolFile: false, symbolFileName: null);

                                key = keys.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == dacFileName);
                            }
                            else
                            {
                                // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
                                key = PEFileKeyGenerator.GetKey(dacFileName, clrInfo.ModuleInfo.TimeStamp, clrInfo.ModuleInfo.FileSize);
                            }

                            if (key != null)
                            {
                                // Now download the DAC module from the symbol server
                                _dacFilePath = SymbolReader.GetSymbolFile(key);
                            }
                        }
                    }

                    if (_dacFilePath == null)
                    {
                        throw new FileNotFoundException($"Could not find matching DAC for this runtime: {clrInfo.ModuleInfo.FileName}");
                    }
                }
                _isDesktop = clrInfo.Flavor == ClrFlavor.Desktop;
            }
            return(_dacFilePath);
        }
Пример #8
0
        private static OpenedReader TryOpenReaderFromCodeView(PEReader peReader, DebugDirectoryEntry codeViewEntry, string assemblyPath)
        {
            OpenedReader           result   = null;
            MetadataReaderProvider provider = null;

            try
            {
                CodeViewDebugDirectoryData data = peReader.ReadCodeViewDebugDirectoryData(codeViewEntry);
                string pdbPath   = data.Path;
                Stream pdbStream = null;

                if (assemblyPath != null)
                {
                    try
                    {
                        pdbPath = Path.Combine(Path.GetDirectoryName(assemblyPath), GetFileName(pdbPath));
                    }
                    catch
                    {
                        // invalid characters in CodeView path
                        return(null);
                    }
                    pdbStream = TryOpenFile(pdbPath);
                }

                if (pdbStream == null)
                {
                    if (s_symbolStore == null)
                    {
                        return(null);
                    }
                    Debug.Assert(codeViewEntry.MinorVersion == ImageDebugDirectory.PortablePDBMinorVersion);
                    SymbolStoreKey key = PortablePDBFileKeyGenerator.GetKey(pdbPath, data.Guid);
                    pdbStream = GetSymbolStoreFile(key)?.Stream;
                }

                provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream);
                MetadataReader reader = provider.GetMetadataReader();

                // Validate that the PDB matches the assembly version
                if (data.Age == 1 && new BlobContentId(reader.DebugMetadataHeader.Id) == new BlobContentId(data.Guid, codeViewEntry.Stamp))
                {
                    result = new OpenedReader(provider, reader);
                }
            }
            catch (Exception e) when(e is BadImageFormatException || e is IOException)
            {
                return(null);
            }
            finally
            {
                if (result == null)
                {
                    provider?.Dispose();
                }
            }

            return(result);
        }
Пример #9
0
 /// <summary>
 /// Attempts to download/retrieve from cache the key.
 /// </summary>
 /// <param name="key">index of the file to retrieve</param>
 /// <returns>stream or null</returns>
 public SymbolStoreFile GetSymbolStoreFile(SymbolStoreKey key)
 {
     if (IsSymbolStoreEnabled)
     {
         return(SymbolReader.GetSymbolStoreFile(key));
     }
     return(null);
 }
Пример #10
0
        private string GetDacFile(ClrInfo clrInfo)
        {
            if (_dacFilePath == null)
            {
                string dacFileName = GetDacFileName(clrInfo, out OSPlatform platform);
                _dacFilePath = GetLocalDacPath(clrInfo, dacFileName);
                if (_dacFilePath == null)
                {
                    if (SymbolReader.IsSymbolStoreEnabled())
                    {
                        SymbolStoreKey key = null;

                        if (platform == OSPlatform.OSX)
                        {
                            unsafe
                            {
                                var memoryService = _serviceProvider.GetService <MemoryService>();
                                SymbolReader.ReadMemoryDelegate readMemory = (ulong address, byte *buffer, int count) => {
                                    return(memoryService.ReadMemory(address, new Span <byte>(buffer, count), out int bytesRead) ? bytesRead : 0);
                                };
                                KeyGenerator generator = SymbolReader.GetKeyGenerator(
                                    SymbolReader.RuntimeConfiguration.OSXCore, clrInfo.ModuleInfo.FileName, clrInfo.ModuleInfo.ImageBase, unchecked ((int)clrInfo.ModuleInfo.FileSize), readMemory);

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

                                key = keys.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == dacFileName);
                            }
                        }
                        else if (platform == OSPlatform.Windows)
                        {
                            // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
                            key = PEFileKeyGenerator.GetKey(dacFileName, clrInfo.ModuleInfo.TimeStamp, clrInfo.ModuleInfo.FileSize);
                        }

                        if (key != null)
                        {
                            // Now download the DAC module from the symbol server
                            _dacFilePath = SymbolReader.GetSymbolFile(key);
                        }
                    }

                    if (_dacFilePath == null)
                    {
                        throw new FileNotFoundException($"Could not find matching DAC for this runtime: {clrInfo.ModuleInfo.FileName}");
                    }
                }
                _isDesktop = clrInfo.Flavor == ClrFlavor.Desktop;
            }
            return(_dacFilePath);
        }
Пример #11
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);
        }
Пример #12
0
 private string GetCacheFilePath(SymbolStoreKey key)
 {
     if (SymbolStoreKey.IsKeyValid(key.Index))
     {
         return(Path.Combine(CacheDirectory, key.Index));
     }
     Tracer.Error("CacheSymbolStore: invalid key index {0}", key.Index);
     return(null);
 }
Пример #13
0
 protected override Task <SymbolStoreFile> GetFileInner(SymbolStoreKey key, CancellationToken token)
 {
     if (_file != null && key.Equals(_key))
     {
         _file.Stream.Position = 0;
         return(Task.FromResult(_file));
     }
     return(Task.FromResult <SymbolStoreFile>(null));
 }
Пример #14
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);
        }
Пример #15
0
 /// <summary>
 /// Attempts to download/retrieve from cache the key.
 /// </summary>
 /// <param name="key">index of the file to retrieve</param>
 /// <returns>stream or null</returns>
 private static SymbolStoreFile GetSymbolStoreFile(SymbolStoreKey key)
 {
     // Add the default symbol cache if it hasn't already been added
     if (!s_symbolCacheAdded)
     {
         s_symbolStore      = new CacheSymbolStore(s_tracer, s_symbolStore, GetDefaultSymbolCache());
         s_symbolCacheAdded = true;
     }
     return(s_symbolStore.GetFile(key, CancellationToken.None).GetAwaiter().GetResult());
 }
Пример #16
0
        private string GetDacFile(ClrInfo clrInfo)
        {
            if (_dacFilePath == null)
            {
                string dac = clrInfo.LocalMatchingDac;
                if (dac != null && File.Exists(dac))
                {
                    _dacFilePath = dac;
                }
                else if (SymbolReader.IsSymbolStoreEnabled())
                {
                    string dacFileName = Path.GetFileName(dac ?? clrInfo.DacInfo.FileName);
                    if (dacFileName != null)
                    {
                        SymbolStoreKey key = null;

                        if (clrInfo.ModuleInfo.BuildId != null)
                        {
                            IEnumerable <SymbolStoreKey> keys = ELFFileKeyGenerator.GetKeys(
                                KeyTypeFlags.ClrKeys, clrInfo.ModuleInfo.FileName, clrInfo.ModuleInfo.BuildId, symbolFile: false, symbolFileName: null);

                            key = keys.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == dacFileName);

                            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                            {
                                // We are opening a Linux dump on Windows
                                // We need to use the Windows index and filename
                                key = new SymbolStoreKey(key.Index.Replace("libmscordaccore.so", "mscordaccore.dll"),
                                                         key.FullPathName.Replace("libmscordaccore.so", "mscordaccore.dll"),
                                                         key.IsClrSpecialFile,
                                                         key.PdbChecksums);
                            }
                        }
                        else
                        {
                            // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
                            key = PEFileKeyGenerator.GetKey(dacFileName, clrInfo.ModuleInfo.TimeStamp, clrInfo.ModuleInfo.FileSize);
                        }

                        if (key != null)
                        {
                            // Now download the DAC module from the symbol server
                            _dacFilePath = SymbolReader.GetSymbolFile(key);
                        }
                    }
                }

                if (_dacFilePath == null)
                {
                    throw new FileNotFoundException($"Could not find matching DAC for this runtime: {clrInfo.ModuleInfo.FileName}");
                }
                _isDesktop = clrInfo.Flavor == ClrFlavor.Desktop;
            }
            return(_dacFilePath);
        }
Пример #17
0
        protected override async Task <SymbolStoreFile> GetFileInner(SymbolStoreKey key, CancellationToken token)
        {
            Uri    uri    = GetRequestUri(key.Index);
            Stream stream = await GetFileStream(uri, token);

            if (stream != null)
            {
                return(new SymbolStoreFile(stream, uri.ToString()));
            }
            return(null);
        }
Пример #18
0
        /// <summary>
        /// Metadata locator helper for the DAC.
        /// </summary>
        /// <param name="imagePath">file name and path to module</param>
        /// <param name="imageTimestamp">module timestamp</param>
        /// <param name="imageSize">module image</param>
        /// <param name="pathBufferSize">output buffer size</param>
        /// <param name="pPathBufferSize">native pointer to put actual path size</param>
        /// <param name="pwszPathBuffer">native pointer to WCHAR path buffer</param>
        /// <returns>HRESULT</returns>
        internal int GetICorDebugMetadataLocator(
            IntPtr self,
            string imagePath,
            uint imageTimestamp,
            uint imageSize,
            uint pathBufferSize,
            IntPtr pPathBufferSize,
            IntPtr pwszPathBuffer)
        {
            int hr         = HResult.S_OK;
            int actualSize = 0;

            Debug.Assert(pwszPathBuffer != IntPtr.Zero);
            try
            {
                if (_symbolService.IsSymbolStoreEnabled)
                {
                    SymbolStoreKey key           = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
                    string         localFilePath = _symbolService.DownloadFile(key);
                    localFilePath += "\0";              // null terminate the string
                    actualSize     = localFilePath.Length;

                    if (pathBufferSize > actualSize)
                    {
                        Trace.TraceInformation($"GetICorDebugMetadataLocator: SUCCEEDED {localFilePath}");
                        Marshal.Copy(localFilePath.ToCharArray(), 0, pwszPathBuffer, actualSize);
                    }
                    else
                    {
                        Trace.TraceError("GetICorDebugMetadataLocator: E_INSUFFICIENT_BUFFER");
                        hr = E_INSUFFICIENT_BUFFER;
                    }
                }
                else
                {
                    Trace.TraceError($"GetICorDebugMetadataLocator: {imagePath} {imageTimestamp:X8} {imageSize:X8} symbol store not enabled");
                    hr = HResult.E_FAIL;
                }
            }
            catch (Exception ex) when
                (ex is UnauthorizedAccessException ||
                ex is BadImageFormatException ||
                ex is InvalidVirtualAddressException ||
                ex is IOException)
            {
                Trace.TraceError($"GetICorDebugMetadataLocator: {imagePath} {imageTimestamp:X8} {imageSize:X8} ERROR {ex.Message}");
                hr = HResult.E_FAIL;
            }
            if (pPathBufferSize != IntPtr.Zero)
            {
                Marshal.WriteInt32(pPathBufferSize, actualSize);
            }
            return(hr);
        }
Пример #19
0
        private string DownloadModule(string moduleName, uint timeStamp, uint sizeOfImage)
        {
            Assert.True(timeStamp != 0 && sizeOfImage != 0);
            SymbolStoreKey key = PEFileKeyGenerator.GetKey(moduleName, timeStamp, sizeOfImage);

            Assert.NotNull(key);
            string downloadedPath = SymbolService.DownloadFile(key);

            Assert.NotNull(downloadedPath);
            return(downloadedPath);
        }
Пример #20
0
        /// <summary>
        /// Finds or downloads the MachO module.
        /// </summary>
        /// <param name="module">module instance</param>
        /// <param name="flags"></param>
        /// <returns>module path or null</returns>
        private string DownloadMachO(IModule module, KeyTypeFlags flags)
        {
            if ((flags & (KeyTypeFlags.IdentityKey | KeyTypeFlags.SymbolKey)) == 0)
            {
                throw new ArgumentException($"Key flag not supported {flags}");
            }

            if (module.BuildId.IsDefaultOrEmpty)
            {
                Trace.TraceWarning($"DownloadMachO: module {module.FileName} has no build id");
                return(null);
            }

            SymbolStoreKey fileKey = MachOFileKeyGenerator.GetKeys(flags, module.FileName, module.BuildId.ToArray(), symbolFile: false, module.GetSymbolFileName()).SingleOrDefault();

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

            // Check if the file is local and the key matches the module
            string fileName = fileKey.FullPathName;

            if (File.Exists(fileName))
            {
                using MachOModule machOModule = MachOModule.OpenFile(fileName);
                if (machOModule is not null)
                {
                    var generator = new MachOFileKeyGenerator(Tracer.Instance, machOModule, fileName);
                    IEnumerable <SymbolStoreKey> keys = generator.GetKeys(flags);
                    foreach (SymbolStoreKey key in keys)
                    {
                        if (fileKey.Equals(key))
                        {
                            Trace.TraceInformation("DownloadMachO: local file match {0}", fileName);
                            return(fileName);
                        }
                    }
                }
            }

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

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

            return(null);
        }
Пример #21
0
        protected override Task <SymbolStoreFile> GetFileInner(SymbolStoreKey key, CancellationToken token)
        {
            SymbolStoreFile result    = null;
            string          cacheFile = GetCacheFilePath(key);

            if (File.Exists(cacheFile))
            {
                Stream fileStream = File.OpenRead(cacheFile);
                result = new SymbolStoreFile(fileStream, cacheFile);
            }
            return(Task.FromResult(result));
        }
Пример #22
0
 /// <summary>
 /// Attempts to download/retrieve from cache the key.
 /// </summary>
 /// <param name="key">index of the file to retrieve</param>
 /// <returns>stream or null</returns>
 private SymbolStoreFile GetSymbolStoreFile(SymbolStoreKey key)
 {
     Debug.Assert(IsSymbolStoreEnabled);
     try
     {
         return(_symbolStore.GetFile(key, CancellationToken.None).GetAwaiter().GetResult());
     }
     catch (Exception ex) when(ex is UnauthorizedAccessException || ex is BadImageFormatException || ex is IOException)
     {
         Trace.TraceError("Exception: {0}", ex.ToString());
     }
     return(null);
 }
Пример #23
0
        /// <summary>
        /// Metadata locator helper for the DAC.
        /// </summary>
        /// <param name="imagePath">file name and path to module</param>
        /// <param name="imageTimestamp">module timestamp</param>
        /// <param name="imageSize">module image</param>
        /// <param name="localFilePath">local file path of the module</param>
        /// <returns>HRESULT</returns>
        public static int GetICorDebugMetadataLocator(
            [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
            uint imageTimestamp,
            uint imageSize,
            uint pathBufferSize,
            IntPtr pPathBufferSize,
            IntPtr pPathBuffer)
        {
            int hr         = S_OK;
            int actualSize = 0;

            Debug.Assert(pPathBuffer != IntPtr.Zero);
            try
            {
                if (SymbolReader.IsSymbolStoreEnabled())
                {
                    SymbolStoreKey key           = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
                    string         localFilePath = SymbolReader.GetSymbolFile(key);
                    localFilePath += "\0";              // null terminate the string
                    actualSize     = localFilePath.Length;

                    if (pathBufferSize > actualSize)
                    {
                        Marshal.Copy(localFilePath.ToCharArray(), 0, pPathBuffer, actualSize);
                    }
                    else
                    {
                        hr = E_INSUFFICIENT_BUFFER;
                    }
                }
                else
                {
                    hr = E_FAIL;
                }
            }
            catch (Exception ex) when
                (ex is UnauthorizedAccessException ||
                ex is BadImageFormatException ||
                ex is InvalidVirtualAddressException ||
                ex is IOException)
            {
                hr = E_FAIL;
            }

            if (pPathBufferSize != IntPtr.Zero)
            {
                Marshal.WriteInt32(pPathBufferSize, actualSize);
            }

            return(hr);
        }
Пример #24
0
        public static int GetMetadataLocator(
            [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
            uint imageTimestamp,
            uint imageSize,
            [MarshalAs(UnmanagedType.LPArray, SizeConst = 16)] byte[] mvid,
            uint mdRva,
            uint flags,
            uint bufferSize,
            IntPtr pMetadata,
            IntPtr pMetadataSize)
        {
            int hr       = unchecked ((int)0x80004005);
            int dataSize = 0;

            Debug.Assert(pMetadata != IntPtr.Zero);

            Stream peStream = null;

            if (imagePath != null && File.Exists(imagePath))
            {
                peStream = SymbolReader.TryOpenFile(imagePath);
            }
            else if (SymbolReader.IsSymbolStoreEnabled())
            {
                SymbolStoreKey key = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
                peStream = SymbolReader.GetSymbolStoreFile(key)?.Stream;
            }
            if (peStream != null)
            {
                using (var peReader = new PEReader(peStream, PEStreamOptions.Default))
                {
                    if (peReader.HasMetadata)
                    {
                        PEMemoryBlock metadataInfo = peReader.GetMetadata();
                        unsafe
                        {
                            int size = Math.Min((int)bufferSize, metadataInfo.Length);
                            Marshal.Copy(metadataInfo.GetContent().ToArray(), 0, pMetadata, size);
                        }
                        dataSize = metadataInfo.Length;
                        hr       = 0;
                    }
                }
            }

            if (pMetadataSize != IntPtr.Zero)
            {
                Marshal.WriteInt32(pMetadataSize, dataSize);
            }
            return(hr);
        }
Пример #25
0
        private string GetDacFile(ClrInfo clrInfo)
        {
            if (s_dacFilePath == null)
            {
                string dac = clrInfo.LocalMatchingDac;
                if (dac != null && File.Exists(dac))
                {
                    s_dacFilePath = dac;
                }
                else if (SymbolReader.IsSymbolStoreEnabled())
                {
                    string dacFileName = Path.GetFileName(dac ?? clrInfo.DacInfo.FileName);
                    if (dacFileName != null)
                    {
                        SymbolStoreKey key = null;

                        if (clrInfo.ModuleInfo.BuildId != null)
                        {
                            IEnumerable <SymbolStoreKey> keys = ELFFileKeyGenerator.GetKeys(
                                KeyTypeFlags.ClrKeys, clrInfo.ModuleInfo.FileName, clrInfo.ModuleInfo.BuildId, symbolFile: false, symbolFileName: null);

                            key = keys.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == dacFileName);
                        }
                        else
                        {
                            // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
                            key = PEFileKeyGenerator.GetKey(dacFileName, clrInfo.ModuleInfo.TimeStamp, clrInfo.ModuleInfo.FileSize);
                        }

                        if (key != null)
                        {
                            if (s_tempDirectory == null)
                            {
                                int processId = Process.GetCurrentProcess().Id;
                                s_tempDirectory = Path.Combine(Path.GetTempPath(), "analyze" + processId.ToString());
                            }
                            // Now download the DAC module from the symbol server
                            s_dacFilePath = SymbolReader.GetSymbolFile(key, s_tempDirectory);
                        }
                    }
                }

                if (s_dacFilePath == null)
                {
                    throw new FileNotFoundException("Could not find matching DAC for this runtime: {0}", clrInfo.ModuleInfo.FileName);
                }
            }

            return(s_dacFilePath);
        }
Пример #26
0
        protected override async Task WriteFileInner(SymbolStoreKey key, SymbolStoreFile file)
        {
            string cacheFile = GetCacheFilePath(key);

            if (cacheFile != null && !File.Exists(cacheFile))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(cacheFile));
                using (Stream destinationStream = File.OpenWrite(cacheFile))
                {
                    await file.Stream.CopyToAsync(destinationStream);

                    Tracer.Information("Cached: {0}", cacheFile);
                }
            }
        }
Пример #27
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);
        }
Пример #28
0
        private string GetDacFile(ClrInfo clrInfo)
        {
            if (_dacFilePath == null)
            {
                string dac = clrInfo.LocalMatchingDac;
                if (dac != null && File.Exists(dac))
                {
                    _dacFilePath = dac;
                }
                else if (SymbolReader.IsSymbolStoreEnabled())
                {
                    string dacFileName = Path.GetFileName(dac ?? clrInfo.DacInfo.FileName);
                    if (dacFileName != null)
                    {
                        SymbolStoreKey key = null;

                        if (clrInfo.ModuleInfo.BuildId != null)
                        {
                            IEnumerable <SymbolStoreKey> keys = ELFFileKeyGenerator.GetKeys(
                                KeyTypeFlags.ClrKeys, clrInfo.ModuleInfo.FileName, clrInfo.ModuleInfo.BuildId, symbolFile: false, symbolFileName: null);

                            key = keys.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == dacFileName);
                        }
                        else
                        {
                            // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
                            key = PEFileKeyGenerator.GetKey(dacFileName, clrInfo.ModuleInfo.TimeStamp, clrInfo.ModuleInfo.FileSize);
                        }

                        if (key != null)
                        {
                            // Now download the DAC module from the symbol server
                            _dacFilePath = SymbolReader.GetSymbolFile(key);
                        }
                    }
                }

                if (_dacFilePath == null)
                {
                    throw new FileNotFoundException($"Could not find matching DAC for this runtime: {clrInfo.ModuleInfo.FileName}");
                }
                _isDesktop = clrInfo.Flavor == ClrFlavor.Desktop;
            }
            return(_dacFilePath);
        }
Пример #29
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);
        }
Пример #30
0
 /// <summary>
 /// Attempts to download/retrieve from cache the key.
 /// </summary>
 /// <param name="key">index of the file to retrieve</param>
 /// <returns>stream or null</returns>
 internal static SymbolStoreFile GetSymbolStoreFile(SymbolStoreKey key)
 {
     try
     {
         // Add the default symbol cache if it hasn't already been added
         if (!s_symbolCacheAdded)
         {
             s_symbolStore      = new CacheSymbolStore(s_tracer, s_symbolStore, GetDefaultSymbolCache());
             s_symbolCacheAdded = true;
         }
         return(s_symbolStore.GetFile(key, CancellationToken.None).GetAwaiter().GetResult());
     }
     catch (Exception ex) when(ex is UnauthorizedAccessException || ex is BadImageFormatException || ex is IOException)
     {
         s_tracer.Error("Exception: {0}", ex.ToString());
         return(null);
     }
 }