// TODO: IAsyncEnumerable when ELF library supports it private IEnumerable <(string debugId, string file)> GetFiles(IEnumerable <string> files) { foreach (var file in files) { _logger.LogInformation("Processing file: {file}.", file); IELF? elf = null; string?buildIdHex; try { // TODO: find an async API if (!ELFReader.TryLoad(file, out elf)) { _logger.LogWarning("Couldn't load': {file} with ELF reader.", file); continue; } var hasBuildId = elf.TryGetSection(".note.gnu.build-id", out var buildId); if (!hasBuildId) { _logger.LogWarning("No Debug Id in {file}", file); continue; } var hasUnwindingInfo = elf.TryGetSection(".eh_frame", out _); var hasDwarfDebugInfo = elf.TryGetSection(".debug_frame", out _); if (!hasUnwindingInfo && !hasDwarfDebugInfo) { _logger.LogWarning("No unwind nor DWARF debug info in {file}", file); continue; } _logger.LogInformation("Contains unwinding info: {hasUnwindingInfo}", hasUnwindingInfo); _logger.LogInformation("Contains DWARF debug info: {hasDwarfDebugInfo}", hasDwarfDebugInfo); var builder = new StringBuilder(); var bytes = buildId.GetContents().Skip(16); foreach (var @byte in bytes) { builder.Append(@byte.ToString("x2")); } buildIdHex = builder.ToString(); } catch (Exception e) { // You would expect TryLoad doesn't throw but that's not the case _logger.LogError(e, "Failed processing file {file}.", file); continue; } finally { elf?.Dispose(); } yield return(buildIdHex, file); } }
public void Dispose() { _inner.Dispose(); try { File.Delete(_tempFilePath); } catch { } }
public void Dispose() { if (_disposed) { return; } _inner.Dispose(); _cleanupAction(); _disposed = true; }
private async Task Collect(string path) { var files = Directory.GetFiles(path); _logger.LogInformation("Path {path} has {length} files to process", path, files.Length); foreach (var file in files) { _logger.LogInformation("Processing file: {file}.", file); IELF elf = null; try { if (!ELFReader.TryLoad(file, out elf)) { _logger.LogWarning("Couldn't load': {file} with ELF reader.", file); continue; } var hasBuildId = elf.TryGetSection(".note.gnu.build-id", out var buildId); if (!hasBuildId) { _logger.LogWarning("No Debug Id in {file}", file); continue; } var hasUnwindingInfo = elf.TryGetSection(".eh_frame", out _); var hasDwarfDebugInfo = elf.TryGetSection(".debug_frame", out _); if (!hasUnwindingInfo && !hasDwarfDebugInfo) { _logger.LogWarning("No unwind nor DWARF debug info in {file}", file); continue; } await ProcessFile(file, hasUnwindingInfo, hasDwarfDebugInfo, buildId, elf); } catch (Exception e) { // You would expect TryLoad doesn't throw but that's not the case _logger.LogError(e, "Failed processing file {file}.", file); } finally { elf?.Dispose(); } } }
/// <inheritdoc/> internal override bool Analyze(DirectoryInfo baseDirectory, FileInfo file) { if (!base.Analyze(baseDirectory, file)) { return(false); } if (!HasMagicBytes(file)) { return(false); } Name = file.Name; Architecture = new Architecture(OS.Linux, Cpu.All); IELF elfData = null; try { if (ELFReader.TryLoad(file.FullName, out elfData)) { if (elfData.Class == Class.NotELF || elfData.Type != FileType.Executable) { return(false); } Architecture = new Architecture(OS.Linux, GetCpu(elfData)); } } catch (NullReferenceException) {} finally { if (elfData != null) { elfData.Dispose(); } } return(true); }