summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2023-10-15 18:56:55 +0200
committerSanto Cariotti <santo@dcariotti.me>2023-10-15 18:56:55 +0200
commit72664d87d2fb0782ca49a5f2118c64d0cf58e3f7 (patch)
tree44f2a3e7a39de1e0aa39ff9997fc9b67bc8eb9d6
parent2affb3567dc7fb42e97da8d5bc7a6b89bdbceb8d (diff)
Add the possibility to redirect the output to a file
-rw-r--r--src/main.rs5
-rw-r--r--src/trace.rs25
2 files changed, 25 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs
index 1859606..1a93aef 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -10,6 +10,9 @@ use nix::unistd::Pid;
struct Args {
/// Command to execute from ptrace
command: String,
+ /// Write the output to a file instead of the standard output
+ #[arg(short = 'f', long = "file")]
+ file_to_print: Option<String>,
}
/// Create a fork of the program and execute the process in the child. Parent gets the pid
@@ -23,7 +26,7 @@ fn main() -> anyhow::Result<()> {
Err(err) => panic!("fork() failed: {err}"),
};
- trace(pid)?;
+ trace(pid, args.file_to_print)?;
Ok(())
}
diff --git a/src/trace.rs b/src/trace.rs
index 04b3ecd..e826c53 100644
--- a/src/trace.rs
+++ b/src/trace.rs
@@ -6,7 +6,12 @@ use nix::{
},
unistd::Pid,
};
-use std::{os::unix::process::CommandExt, process::Command};
+use std::{
+ fs::File,
+ io::{self, Write},
+ os::unix::process::CommandExt,
+ process::Command,
+};
/// Exec the `command` value tracing it with `ptrace` lib
pub fn exec(command: &String) -> anyhow::Result<()> {
@@ -25,7 +30,7 @@ pub fn exec(command: &String) -> anyhow::Result<()> {
}
/// Trace a process with `pid` ID
-pub fn trace(pid: Pid) -> anyhow::Result<()> {
+pub fn trace(pid: Pid, file_to_print: Option<String>) -> anyhow::Result<()> {
// Since you have to do 2 syscalls (start and end) you have to alternate the print value,
// because it could be equals except for the `rax` register.
let mut have_to_print = true;
@@ -33,6 +38,13 @@ pub fn trace(pid: Pid) -> anyhow::Result<()> {
// First wait for the parent process
_ = waitpid(pid, None)?;
+ // If `fiole_to_print` is not None, create a new file with that value for redirecting all the
+ // output (also in stdout)
+ let mut f = None;
+ if let Some(filename) = file_to_print {
+ f = Some(File::create(filename)?);
+ }
+
loop {
have_to_print ^= true;
ptrace::syscall(pid, None)?;
@@ -49,10 +61,15 @@ pub fn trace(pid: Pid) -> anyhow::Result<()> {
Signal::SIGTRAP => {
let regs = ptrace::getregs(pid)?;
if have_to_print {
- println!(
+ let output = format!(
"{}({:x}, {:x}, {:x}, ...) = {:x}",
- regs.orig_rax, regs.rdi, regs.rsi, regs.rdx, regs.rax,
+ regs.orig_rax, regs.rdi, regs.rsi, regs.rdx, regs.rax
);
+ writeln!(io::stdout(), "{output}")?;
+
+ if let Some(ref mut f) = f {
+ writeln!(f, "{output}")?;
+ }
}
}
_ => {}