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); }
/// <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); }
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); } } }
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); } } } } } }
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); } } } } } }
/// <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); } } }
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); }
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); }
/// <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); }
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); }
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); }
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); }
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)); }
/// <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); }
/// <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()); }
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); }
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); }
/// <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); }
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); }
/// <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); }
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)); }
/// <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); }
/// <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); }
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); }
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); }
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); } } }
/// <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); }
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); }
/// <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); }
/// <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); } }