Skip to content

Commit

Permalink
Restore --trace-points
Browse files Browse the repository at this point in the history
  • Loading branch information
encounter committed Aug 13, 2024
1 parent b87da6d commit e0f2f65
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
45 changes: 41 additions & 4 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[cfg(not(feature = "x86-64"))]
#[cfg(any(feature = "x86-emu", feature = "x86-unicorn"))]
mod debugger;
mod host;
mod logging;
Expand Down Expand Up @@ -28,6 +28,11 @@ struct Args {
#[argh(option)]
win32_trace: Option<String>,

/// log CPU state first time each point reached
#[cfg(any(feature = "x86-emu", feature = "x86-unicorn"))]
#[argh(option, from_str_fn(parse_trace_points))]
trace_points: Option<std::collections::VecDeque<u32>>,

/// enable GDB stub
#[argh(switch)]
#[cfg(any(feature = "x86-emu", feature = "x86-unicorn"))]
Expand Down Expand Up @@ -81,6 +86,19 @@ fn print_trace(machine: &win32::Machine) {
println!("@{eip:x}\n eax:{eax:x} ebx:{ebx:x} ecx:{ecx:x} edx:{edx:x} esi:{esi:x} edi:{edi:x} esp:{esp:x} ebp:{ebp:x} st_top:{st_top}");
}

#[cfg(any(feature = "x86-emu", feature = "x86-unicorn"))]
fn parse_trace_points(param: &str) -> Result<std::collections::VecDeque<u32>, String> {
let mut trace_points = std::collections::VecDeque::new();
for addr in param.split(",") {
if addr.is_empty() {
continue;
}
let addr = u32::from_str_radix(addr, 16).map_err(|_| format!("bad addr {addr:?}"))?;
trace_points.push_back(addr);
}
Ok(trace_points)
}

fn main() -> anyhow::Result<ExitCode> {
#[cfg(feature = "x86-64")]
unsafe {
Expand Down Expand Up @@ -166,6 +184,13 @@ fn main() -> anyhow::Result<ExitCode> {
}
let mut ctx = std::task::Context::from_waker(futures::task::noop_waker_ref());
let mut shim_calls = Vec::<AsyncShimCall>::new();

let mut trace_points_iter = args.trace_points.iter().flatten().copied();
let mut trace_point = trace_points_iter.next();
if let Some(address) = trace_point {
target.machine.add_breakpoint(address);
}

let exit_code = loop {
let mut instruction_count = 0; // used to step a single instruction or range
match debugger.poll(&mut target)? {
Expand Down Expand Up @@ -222,9 +247,21 @@ fn main() -> anyhow::Result<ExitCode> {
break ExitCode::from(code.try_into().unwrap_or(u8::MAX));
}
win32::StopReason::Breakpoint { eip } => {
log::info!("Breakpoint hit @ {eip:x}");
debugger.breakpoint(&mut target)?;
MachineState::Stopped
if trace_point == Some(eip) {
target.machine.clear_breakpoint(eip);
print_trace(&target.machine);
trace_point = trace_points_iter.next();
if let Some(address) = trace_point {
target.machine.add_breakpoint(address);
MachineState::Running
} else {
break ExitCode::SUCCESS;
}
} else {
log::info!("Breakpoint hit @ {eip:x}");
debugger.breakpoint(&mut target)?;
MachineState::Stopped
}
}
win32::StopReason::ShimCall(shim) => {
// log::info!("Shim call {}", shim.name);
Expand Down
1 change: 0 additions & 1 deletion x86/src/ops/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,6 @@ pub fn cdq(cpu: &mut CPU, _mem: Mem, _instr: &Instruction) {
}

pub fn int3(cpu: &mut CPU, _mem: Mem, _instr: &Instruction) {
log::warn!("debugger interrupt");
cpu.state = CPUState::DebugBreak;
cpu.regs.eip -= 1;
}
Expand Down

0 comments on commit e0f2f65

Please sign in to comment.