diff --git a/src/main.rs b/src/main.rs index 2740b06..2dbe304 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,7 +36,11 @@ fn main() -> anyhow::Result<()> { // Get versions let sd_version = systemd::SystemdVersion::local_system()?; let kernel_version = systemd::KernelVersion::local_system()?; - log::info!("Detected Systemd version: {sd_version}, Linux kernel version: {kernel_version}"); + let strace_version = strace::StraceVersion::local_system()?; + log::info!("Detected versions: Systemd {sd_version}, Linux kernel {kernel_version}, strace {strace_version}"); + if strace_version < strace::StraceVersion::new(6, 4) { + log::warn!("Strace version >=6.4 is strongly recommended, if you experience strace output parsing errors, please consider upgrading") + } // Parse cl args let args = cl::Args::parse(); diff --git a/src/strace/mod.rs b/src/strace/mod.rs index 1fc9eac..2f774a3 100644 --- a/src/strace/mod.rs +++ b/src/strace/mod.rs @@ -1,6 +1,10 @@ //! Strace related code use std::collections::HashMap; +use std::fmt; +use std::io::BufRead; +use std::process::Command; +use std::str; mod parser; mod run; @@ -82,3 +86,43 @@ impl IntegerExpression { } pub type SyscallRetVal = i128; // allows holding both signed and unsigned 64 bit integers + +#[derive(Ord, PartialOrd, Eq, PartialEq)] +pub struct StraceVersion { + pub major: u16, + pub minor: u16, +} + +impl StraceVersion { + pub fn new(major: u16, minor: u16) -> Self { + Self { major, minor } + } + + pub fn local_system() -> anyhow::Result { + let output = Command::new("strace").arg("--version").output()?; + if !output.status.success() { + anyhow::bail!("strace invocation failed with code {:?}", output.status); + } + let version_line = output + .stdout + .lines() + .next() + .ok_or_else(|| anyhow::anyhow!("Unable to get strace version"))??; + let (major, minor) = version_line + .rsplit_once(' ') + .ok_or_else(|| anyhow::anyhow!("Unable to get strace version"))? + .1 + .split_once('.') + .ok_or_else(|| anyhow::anyhow!("Unable to get strace version"))?; + Ok(Self { + major: major.parse()?, + minor: minor.parse()?, + }) + } +} + +impl fmt::Display for StraceVersion { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}.{}", self.major, self.minor) + } +}