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