Skip to content
This repository was archived by the owner on Nov 1, 2023. It is now read-only.

Commit 1a059f2

Browse files
authored
Add context to coverage tracing errors (#979)
1 parent b39f096 commit 1a059f2

File tree

2 files changed

+44
-21
lines changed

2 files changed

+44
-21
lines changed

src/agent/coverage/src/block/linux.rs

+35-15
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,28 @@ impl<'c> Recorder<'c> {
7171
options.remove(Options::PTRACE_O_TRACEFORK);
7272
options.remove(Options::PTRACE_O_TRACEVFORK);
7373
options.remove(Options::PTRACE_O_TRACEEXEC);
74-
tracee.set_options(options)?;
74+
tracee
75+
.set_options(options)
76+
.context("setting tracee options")?;
7577

7678
self.images = Some(Images::new(tracee.pid.as_raw()));
77-
self.update_images(&mut tracee)?;
79+
self.update_images(&mut tracee)
80+
.context("initial update of module images")?;
7881

79-
self.tracer.restart(tracee, Restart::Syscall)?;
82+
self.tracer
83+
.restart(tracee, Restart::Syscall)
84+
.context("initial tracer restart")?;
8085

81-
while let Some(mut tracee) = self.tracer.wait()? {
86+
while let Some(mut tracee) = self.tracer.wait().context("main tracing loop")? {
8287
match tracee.stop {
8388
Stop::SyscallEnterStop(..) => log::trace!("syscall-enter: {:?}", tracee.stop),
8489
Stop::SyscallExitStop(..) => {
85-
self.update_images(&mut tracee)?;
90+
self.update_images(&mut tracee)
91+
.context("updating module images after syscall-stop")?;
8692
}
8793
Stop::SignalDeliveryStop(_pid, Signal::SIGTRAP) => {
88-
self.on_breakpoint(&mut tracee)?;
94+
self.on_breakpoint(&mut tracee)
95+
.context("calling breakpoint handler")?;
8996
}
9097
Stop::Clone(pid, tid) => {
9198
// Only seen when the `VM_CLONE` flag is set, as of Linux 4.15.
@@ -113,7 +120,8 @@ impl<'c> Recorder<'c> {
113120

114121
for (_base, image) in &events.loaded {
115122
if self.filter.includes_module(image.path()) {
116-
self.on_module_load(tracee, image)?;
123+
self.on_module_load(tracee, image)
124+
.context("module load callback")?;
117125
}
118126
}
119127

@@ -137,12 +145,16 @@ impl<'c> Recorder<'c> {
137145
.find_va_image(pc)
138146
.ok_or_else(|| format_err!("unable to find image for va = {:x}", pc))?;
139147

140-
let offset = image.va_to_offset(pc)?;
148+
let offset = image
149+
.va_to_offset(pc)
150+
.context("converting PC to module offset")?;
141151
self.coverage.increment(image.path(), offset);
142152

143153
// Execute clobbered instruction on restart.
144154
regs.rip = pc;
145-
tracee.set_registers(regs)?;
155+
tracee
156+
.set_registers(regs)
157+
.context("resetting PC in breakpoint handler")?;
146158
} else {
147159
// Assume the tracee concurrently executed an `int3` that we restored
148160
// in another handler.
@@ -151,7 +163,9 @@ impl<'c> Recorder<'c> {
151163
// clearing, but making their value a state.
152164
log::debug!("no breakpoint at {:x}, assuming race", pc);
153165
regs.rip = pc;
154-
tracee.set_registers(regs)?;
166+
tracee
167+
.set_registers(regs)
168+
.context("resetting PC after ignoring spurious breakpoint")?;
155169
}
156170

157171
Ok(())
@@ -233,11 +247,11 @@ impl Images {
233247
}
234248

235249
pub fn update(&mut self) -> Result<LoadEvents> {
236-
let proc = Process::new(self.pid)?;
250+
let proc = Process::new(self.pid).context("getting procinfo")?;
237251

238252
let mut new = BTreeMap::default();
239253

240-
for map in proc.maps()? {
254+
for map in proc.maps().context("getting maps for process")? {
241255
if let Ok(image) = ModuleImage::new(map) {
242256
new.insert(image.base(), image);
243257
}
@@ -374,7 +388,9 @@ impl Breakpoints {
374388
let mut data = [0u8];
375389
tracee.read_memory_mut(va, &mut data)?;
376390
self.saved.insert(va, data[0]);
377-
tracee.write_memory(va, &[0xcc])?;
391+
tracee
392+
.write_memory(va, &[0xcc])
393+
.context("setting breakpoint, writing int3")?;
378394

379395
Ok(())
380396
}
@@ -383,7 +399,9 @@ impl Breakpoints {
383399
let data = self.saved.remove(&va);
384400

385401
let cleared = if let Some(data) = data {
386-
tracee.write_memory(va, &[data])?;
402+
tracee
403+
.write_memory(va, &[data])
404+
.context("clearing breakpoint, restoring byte")?;
387405
true
388406
} else {
389407
false
@@ -399,7 +417,9 @@ fn continue_to_init_execve(tracer: &mut Ptracer) -> Result<Tracee> {
399417
return Ok(tracee);
400418
}
401419

402-
tracer.restart(tracee, Restart::Continue)?;
420+
tracer
421+
.restart(tracee, Restart::Continue)
422+
.context("restarting tracee pre-execve()")?;
403423
}
404424

405425
anyhow::bail!("did not see initial execve() in tracee while recording coverage");

src/agent/coverage/src/block/windows.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::collections::BTreeMap;
55
use std::process::Command;
66
use std::time::{Duration, Instant};
77

8-
use anyhow::Result;
8+
use anyhow::{Context, Result};
99
use debugger::{BreakpointId, BreakpointType, DebugEventHandler, Debugger, ModuleLoadInfo};
1010

1111
use crate::block::CommandBlockCov;
@@ -50,8 +50,8 @@ impl<'r, 'c> RecorderEventHandler<'r, 'c> {
5050
}
5151

5252
pub fn run(&mut self, cmd: Command) -> Result<()> {
53-
let (mut dbg, _child) = Debugger::init(cmd, self)?;
54-
dbg.run(self)?;
53+
let (mut dbg, _child) = Debugger::init(cmd, self).context("initializing debugger")?;
54+
dbg.run(self).context("running debuggee")?;
5555
Ok(())
5656
}
5757

@@ -129,7 +129,9 @@ impl<'c> Recorder<'c> {
129129
if log::max_level() == log::Level::Trace {
130130
let name = breakpoint.module.name().to_string_lossy();
131131
let offset = breakpoint.offset;
132-
let pc = dbg.read_program_counter()?;
132+
let pc = dbg
133+
.read_program_counter()
134+
.context("reading PC on breakpoint")?;
133135

134136
if let Ok(sym) = dbg.get_symbol(pc) {
135137
log::trace!(
@@ -161,7 +163,7 @@ impl<'c> Recorder<'c> {
161163
}
162164

163165
fn insert_module(&mut self, dbg: &mut Debugger, module: &ModuleLoadInfo) -> Result<()> {
164-
let path = ModulePath::new(module.path().to_owned())?;
166+
let path = ModulePath::new(module.path().to_owned()).context("parsing module path")?;
165167

166168
if !self.filter.includes_module(&path) {
167169
log::debug!("skipping module: {}", path);
@@ -182,7 +184,8 @@ impl<'c> Recorder<'c> {
182184
}
183185

184186
self.breakpoints
185-
.set(dbg, module, info.blocks.iter().copied())?;
187+
.set(dbg, module, info.blocks.iter().copied())
188+
.context("setting breakpoints for module")?;
186189

187190
log::debug!("set {} breakpoints for module {}", info.blocks.len(), path);
188191
}

0 commit comments

Comments
 (0)