use crate::debugger::error::Error;
use std::path::{Path, PathBuf};
pub fn find_dependencies(file: &Path) -> Result<Vec<PathBuf>, Error> {
let mut cmd = std::process::Command::new("ldd");
let output = cmd.arg(file.to_string_lossy().as_ref()).output()?;
let output = std::str::from_utf8(&output.stdout)?;
Ok(parse_ldd_output(output))
}
fn parse_ldd_output(output: &str) -> Vec<PathBuf> {
output
.lines()
.filter_map(|s| {
let s = s.trim();
let s = s.split("=>").last();
s.and_then(|s| s.split_whitespace().next())
})
.map(PathBuf::from)
.collect()
}
#[cfg(test)]
mod test {
use crate::debugger::debugee::ldd::parse_ldd_output;
use std::path::PathBuf;
#[test]
fn test_ldd_output_parsing() {
struct TestCase {
ldd_output: &'static str,
expected: Vec<PathBuf>,
}
let test_cases = [
TestCase {
ldd_output: " linux-vdso.so.1 (0x00007ffd69ff4000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f66730e7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6672e00000)
/lib64/ld-linux-x86-64.so.2 (0x00007f66732b3000)
",
expected: vec![
PathBuf::from("linux-vdso.so.1"),
PathBuf::from("/lib/x86_64-linux-gnu/libgcc_s.so.1"),
PathBuf::from("/lib/x86_64-linux-gnu/libc.so.6"),
PathBuf::from("/lib64/ld-linux-x86-64.so.2"),
],
},
TestCase {
ldd_output: "/lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2
",
expected: vec![
PathBuf::from("/lib/x86_64-linux-gnu/libc.so.6"),
PathBuf::from("/lib64/ld-linux-x86-64.so.2"),
],
},
];
for tc in test_cases {
let result = parse_ldd_output(tc.ldd_output);
assert_eq!(result, tc.expected);
}
}
}