fmt
This commit is contained in:
parent
62f7e40c64
commit
fbc5634ad9
|
@ -1,13 +1,17 @@
|
||||||
use std::{
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
collections::{BTreeMap, HashMap, HashSet},
|
collections::{BTreeMap, HashMap, HashSet},
|
||||||
fs, io,
|
fs, io,
|
||||||
path::PathBuf, borrow::Cow,
|
path::PathBuf,
|
||||||
};
|
};
|
||||||
|
|
||||||
use gimli::{constants, DW_TAG_compile_unit};
|
use gimli::{constants, DW_TAG_compile_unit};
|
||||||
|
use object::{Object, ObjectSection, ReadCache};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::{digest::generic_array::{GenericArray, typenum::U32}, Digest, Sha256};
|
use sha2::{
|
||||||
use object::{Object, ReadCache, ObjectSection};
|
digest::generic_array::{typenum::U32, GenericArray},
|
||||||
|
Digest, Sha256,
|
||||||
|
};
|
||||||
use typed_arena::Arena;
|
use typed_arena::Arena;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||||
|
@ -20,7 +24,7 @@ pub struct Sha256Hash {
|
||||||
impl From<GenericArray<u8, U32>> for Sha256Hash {
|
impl From<GenericArray<u8, U32>> for Sha256Hash {
|
||||||
fn from(value: GenericArray<u8, U32>) -> Self {
|
fn from(value: GenericArray<u8, U32>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: value.into()
|
inner: value.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,9 +47,7 @@ pub struct FileStoreEntry {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum FileFormat {
|
pub enum FileFormat {
|
||||||
ELF {
|
ELF { references: Vec<usize> },
|
||||||
references: Vec<usize>,
|
|
||||||
},
|
|
||||||
Other,
|
Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,8 +118,7 @@ impl FileStore {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if index == self.files.len() {
|
if index == self.files.len() {}
|
||||||
}
|
|
||||||
|
|
||||||
self.filenames.insert(filename, index);
|
self.filenames.insert(filename, index);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -201,12 +202,16 @@ impl FileStore {
|
||||||
if entry.tag() == DW_TAG_compile_unit {
|
if entry.tag() == DW_TAG_compile_unit {
|
||||||
let mut basename = None;
|
let mut basename = None;
|
||||||
let mut dirname = None;
|
let mut dirname = None;
|
||||||
if let Some(name) = entry.attr(constants::DW_AT_name)?.map(|a| a.value()) {
|
if let Some(name) =
|
||||||
|
entry.attr(constants::DW_AT_name)?.map(|a| a.value())
|
||||||
|
{
|
||||||
if let Ok(name) = dwarf.attr_string(&dwarf.unit(unit)?, name) {
|
if let Ok(name) = dwarf.attr_string(&dwarf.unit(unit)?, name) {
|
||||||
basename = Some(PathBuf::from(name.to_string()?));
|
basename = Some(PathBuf::from(name.to_string()?));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(name) = entry.attr(constants::DW_AT_comp_dir)?.map(|a| a.value()) {
|
if let Some(name) =
|
||||||
|
entry.attr(constants::DW_AT_comp_dir)?.map(|a| a.value())
|
||||||
|
{
|
||||||
if let Ok(name) = dwarf.attr_string(&dwarf.unit(unit)?, name) {
|
if let Ok(name) = dwarf.attr_string(&dwarf.unit(unit)?, name) {
|
||||||
dirname = Some(PathBuf::from(name.to_string()?));
|
dirname = Some(PathBuf::from(name.to_string()?));
|
||||||
}
|
}
|
||||||
|
@ -218,11 +223,15 @@ impl FileStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let references = inputs.into_iter().map(|input| self.ingest_dependency_local(input)).collect::<Result<Vec<_>, _>>()?.into_iter().filter_map(|x| x).collect();
|
let references = inputs
|
||||||
FileFormat::ELF {
|
.into_iter()
|
||||||
references,
|
.map(|input| self.ingest_dependency_local(input))
|
||||||
}
|
.collect::<Result<Vec<_>, _>>()?
|
||||||
},
|
.into_iter()
|
||||||
|
.filter_map(|x| x)
|
||||||
|
.collect();
|
||||||
|
FileFormat::ELF { references }
|
||||||
|
}
|
||||||
_ => FileFormat::Other,
|
_ => FileFormat::Other,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
36
src/main.rs
36
src/main.rs
|
@ -1,6 +1,6 @@
|
||||||
mod tracer;
|
|
||||||
mod filestore;
|
mod filestore;
|
||||||
mod reports;
|
mod reports;
|
||||||
|
mod tracer;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
@ -38,16 +38,27 @@ enum Subcommands {
|
||||||
|
|
||||||
/// The filepath to dump the json report to. will dump to stdout if unspecified.
|
/// The filepath to dump the json report to. will dump to stdout if unspecified.
|
||||||
output: Option<PathBuf>,
|
output: Option<PathBuf>,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
match cli.cmd {
|
match cli.cmd {
|
||||||
Subcommands::Run { file_scope, output, cmd, mute } => {
|
Subcommands::Run {
|
||||||
|
file_scope,
|
||||||
|
output,
|
||||||
|
cmd,
|
||||||
|
mute,
|
||||||
|
} => {
|
||||||
let fp: Box<dyn std::io::Write> = if let Some(output) = &output {
|
let fp: Box<dyn std::io::Write> = if let Some(output) = &output {
|
||||||
Box::new(std::fs::File::options().write(true).create(true).open(output).unwrap())
|
Box::new(
|
||||||
|
std::fs::File::options()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.open(output)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
Box::new(std::io::stdout())
|
Box::new(std::io::stdout())
|
||||||
};
|
};
|
||||||
|
@ -58,11 +69,18 @@ fn main() {
|
||||||
serde_json::to_writer_pretty(fp, &t.report)
|
serde_json::to_writer_pretty(fp, &t.report)
|
||||||
} else {
|
} else {
|
||||||
serde_json::to_writer(fp, &t.report)
|
serde_json::to_writer(fp, &t.report)
|
||||||
}.expect("Could not serialize json trace report");
|
}
|
||||||
|
.expect("Could not serialize json trace report");
|
||||||
}
|
}
|
||||||
Subcommands::QueryParameters { input, output } => {
|
Subcommands::QueryParameters { input, output } => {
|
||||||
let fp: Box<dyn std::io::Write> = if let Some(output) = &output {
|
let fp: Box<dyn std::io::Write> = if let Some(output) = &output {
|
||||||
Box::new(std::fs::File::options().write(true).create(true).open(output).unwrap())
|
Box::new(
|
||||||
|
std::fs::File::options()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.open(output)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
Box::new(std::io::stdout())
|
Box::new(std::io::stdout())
|
||||||
};
|
};
|
||||||
|
@ -71,7 +89,8 @@ fn main() {
|
||||||
serde_json::from_reader(std::fs::File::open(input).unwrap())
|
serde_json::from_reader(std::fs::File::open(input).unwrap())
|
||||||
} else {
|
} else {
|
||||||
serde_json::from_reader(std::io::stdin())
|
serde_json::from_reader(std::io::stdin())
|
||||||
}.expect("Could not deserialize json trace report");
|
}
|
||||||
|
.expect("Could not deserialize json trace report");
|
||||||
|
|
||||||
let out_report = reports::parameters::run(&in_report).unwrap();
|
let out_report = reports::parameters::run(&in_report).unwrap();
|
||||||
|
|
||||||
|
@ -79,7 +98,8 @@ fn main() {
|
||||||
serde_json::to_writer_pretty(fp, &out_report)
|
serde_json::to_writer_pretty(fp, &out_report)
|
||||||
} else {
|
} else {
|
||||||
serde_json::to_writer(fp, &out_report)
|
serde_json::to_writer(fp, &out_report)
|
||||||
}.expect("Could not serialize json parameter report");
|
}
|
||||||
|
.expect("Could not serialize json parameter report");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,18 @@ use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
ffi::CString,
|
ffi::CString,
|
||||||
ffi::OsString,
|
ffi::OsString,
|
||||||
os::{fd::{AsRawFd}, unix::prelude::OsStringExt},
|
fmt::{Display, Formatter},
|
||||||
|
os::{fd::AsRawFd, unix::prelude::OsStringExt},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
process::exit,
|
process::exit,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
fmt::{Display, Formatter},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
use nix::{
|
use nix::{
|
||||||
errno::Errno,
|
errno::Errno,
|
||||||
libc::{pid_t, raise, tcsetpgrp, AT_EMPTY_PATH, SIGSTOP, STDIN_FILENO, AT_FDCWD},
|
libc::{pid_t, raise, tcsetpgrp, AT_EMPTY_PATH, AT_FDCWD, SIGSTOP, STDIN_FILENO},
|
||||||
sys::{
|
sys::{
|
||||||
ptrace::{self, traceme, AddressType},
|
ptrace::{self, traceme, AddressType},
|
||||||
signal::Signal,
|
signal::Signal,
|
||||||
|
@ -446,10 +446,7 @@ impl Tracer {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
store: ProcessStateStore::default(),
|
store: ProcessStateStore::default(),
|
||||||
start_time: Instant::now(),
|
start_time: Instant::now(),
|
||||||
report: TracerReport {
|
report: TracerReport { log: vec![], files },
|
||||||
log: vec![],
|
|
||||||
files,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,7 +582,14 @@ impl Tracer {
|
||||||
// So we need to determine whether exec is successful here.
|
// So we need to determine whether exec is successful here.
|
||||||
// PTRACE_EVENT_EXEC only happens for successful exec.
|
// PTRACE_EVENT_EXEC only happens for successful exec.
|
||||||
p.is_exec_successful = true;
|
p.is_exec_successful = true;
|
||||||
let path = p.pending_syscall_event.iter().find_map(|e| match e { Event::Exec { prog, .. } => Some(prog.clone()), _ => None }).unwrap();
|
let path = p
|
||||||
|
.pending_syscall_event
|
||||||
|
.iter()
|
||||||
|
.find_map(|e| match e {
|
||||||
|
Event::Exec { prog, .. } => Some(prog.clone()),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
self.report.files.ingest_output_local(path)?;
|
self.report.files.ingest_output_local(path)?;
|
||||||
self.drain_syscall_events(pid.into(), Box::new(|_| {}));
|
self.drain_syscall_events(pid.into(), Box::new(|_| {}));
|
||||||
// Don't use seccomp_aware_cont here because that will skip the next syscall exit stop
|
// Don't use seccomp_aware_cont here because that will skip the next syscall exit stop
|
||||||
|
@ -634,10 +638,17 @@ impl Tracer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if mute {
|
if mute {
|
||||||
let null = std::fs::File::options().read(true).write(true).open("/dev/null").expect("Could not open /dev/null");
|
let null = std::fs::File::options()
|
||||||
nix::unistd::dup2(null.as_raw_fd(), 0).expect("Could not dup /dev/null to /dev/stdin");
|
.read(true)
|
||||||
nix::unistd::dup2(null.as_raw_fd(), 1).expect("Could not dup /dev/null to /dev/stdout");
|
.write(true)
|
||||||
nix::unistd::dup2(null.as_raw_fd(), 2).expect("Could not dup /dev/null to /dev/stderr");
|
.open("/dev/null")
|
||||||
|
.expect("Could not open /dev/null");
|
||||||
|
nix::unistd::dup2(null.as_raw_fd(), 0)
|
||||||
|
.expect("Could not dup /dev/null to /dev/stdin");
|
||||||
|
nix::unistd::dup2(null.as_raw_fd(), 1)
|
||||||
|
.expect("Could not dup /dev/null to /dev/stdout");
|
||||||
|
nix::unistd::dup2(null.as_raw_fd(), 2)
|
||||||
|
.expect("Could not dup /dev/null to /dev/stderr");
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = args
|
let args = args
|
||||||
|
@ -780,7 +791,11 @@ impl Tracer {
|
||||||
nix::libc::SYS_open | nix::libc::SYS_openat => {
|
nix::libc::SYS_open | nix::libc::SYS_openat => {
|
||||||
if result >= 0 {
|
if result >= 0 {
|
||||||
for pending in p.pending_syscall_event.iter_mut() {
|
for pending in p.pending_syscall_event.iter_mut() {
|
||||||
if let Event::FdOpen { source: FdSource::File { path }, .. } = pending {
|
if let Event::FdOpen {
|
||||||
|
source: FdSource::File { path },
|
||||||
|
..
|
||||||
|
} = pending
|
||||||
|
{
|
||||||
self.report.files.ingest_output_local(path.clone())?;
|
self.report.files.ingest_output_local(path.clone())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue