Skip to content

Commit fdaf2a4

Browse files
committed
Handle the last TODO
1 parent b413258 commit fdaf2a4

2 files changed

Lines changed: 28 additions & 67 deletions

File tree

src/process_handling/event_source.rs

Lines changed: 23 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,16 @@ use nix::{
1010
},
1111
unistd::Pid,
1212
};
13-
use procfs::process::{MMapPath, Process};
13+
use procfs::process::{MMapPath, Process, Task};
14+
use tracing::info;
1415

1516
pub trait EventSource {
1617
fn request_trace(&self) -> nix::Result<()>;
1718
fn get_offset(&self, pid: Pid, config: &Config) -> u64;
1819
fn trace_children(&self, pid: Pid) -> nix::Result<()>;
20+
/// This will be at the start of every wait/handle/continue loop so can be used to pop out and
21+
/// apply state changes which occur when tests are running for any mock event sources. In real
22+
/// life the actual processes under test will be modifying things!
1923
fn waitpid(&self, pid: Pid, options: Option<WaitPidFlag>) -> nix::Result<WaitStatus>;
2024
fn next_events(&self, wait_queue: &mut Vec<WaitStatus>) -> Result<Option<TestState>, RunError>;
2125
fn get_event_data(&self, pid: Pid) -> nix::Result<c_long>;
@@ -26,6 +30,9 @@ pub trait EventSource {
2630
fn set_current_instruction_pointer(&self, pid: Pid, addr: u64) -> nix::Result<c_long>;
2731
fn write_address(&self, pid: Pid, addr: u64, data: c_long) -> nix::Result<()>;
2832
fn read_address(&self, pid: Pid, addr: u64) -> nix::Result<c_long>;
33+
34+
fn get_tasks(&self, pid: Pid) -> Box<dyn Iterator<Item = Task> + '_>;
35+
fn get_ppid(&self, pid: Pid) -> Option<Pid>;
2936
}
3037

3138
#[derive(Clone)]
@@ -137,61 +144,23 @@ impl EventSource for PtraceEventSource {
137144
fn read_address(&self, pid: Pid, address: u64) -> nix::Result<c_long> {
138145
read_address(pid, address)
139146
}
140-
}
141-
142-
#[derive(Clone)]
143-
pub struct ReplayEventSource {}
144-
145-
impl EventSource for ReplayEventSource {
146-
fn request_trace(&self) -> nix::Result<()> {
147-
Ok(())
148-
}
149-
150-
fn get_offset(&self, pid: Pid, config: &Config) -> u64 {
151-
0
152-
}
153-
154-
fn trace_children(&self, pid: Pid) -> nix::Result<()> {
155-
todo!()
156-
}
157-
158-
fn waitpid(&self, pid: Pid, options: Option<WaitPidFlag>) -> nix::Result<WaitStatus> {
159-
todo!()
160-
}
161-
162-
fn next_events(&self, wait_queue: &mut Vec<WaitStatus>) -> Result<Option<TestState>, RunError> {
163-
todo!();
164-
}
165-
166-
fn get_event_data(&self, pid: Pid) -> nix::Result<c_long> {
167-
todo!()
168-
}
169147

170-
fn continue_pid(&self, pid: Pid, signal: Option<Signal>) -> nix::Result<()> {
171-
todo!();
172-
}
173-
174-
fn single_step(&self, pid: Pid) -> nix::Result<()> {
175-
todo!();
176-
}
177-
178-
fn detach_child(&self, pid: Pid) -> nix::Result<()> {
179-
todo!()
180-
}
181-
182-
fn current_instruction_pointer(&self, pid: Pid) -> nix::Result<c_long> {
183-
todo!();
184-
}
185-
186-
fn set_current_instruction_pointer(&self, pid: Pid, addr: u64) -> nix::Result<c_long> {
187-
todo!();
188-
}
189-
190-
fn write_address(&self, pid: Pid, address: u64, data: c_long) -> nix::Result<()> {
191-
todo!();
148+
fn get_tasks(&self, pid: Pid) -> Box<dyn Iterator<Item = Task> + '_> {
149+
if let Some(proc) = Process::new(pid.as_raw()).ok().and_then(|x| x.tasks().ok()) {
150+
Box::new(proc.filter_map(Result::ok))
151+
} else {
152+
Box::new(std::iter::empty())
153+
}
192154
}
193155

194-
fn read_address(&self, pid: Pid, address: u64) -> nix::Result<c_long> {
195-
todo!();
156+
fn get_ppid(&self, pid: Pid) -> Option<Pid> {
157+
let proc = Process::new(pid.as_raw()).ok()?;
158+
if let Ok(status) = proc.status() {
159+
info!("Found potential parent");
160+
let pid = Pid::from_raw(status.ppid);
161+
Some(pid)
162+
} else {
163+
None
164+
}
196165
}
197166
}

src/statemachine/linux.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -394,23 +394,15 @@ impl<'a> LinuxData<'a> {
394394
let mut parent_pid = None;
395395
'outer: for k in self.processes.keys() {
396396
// TODO should be in the event source stuff
397-
let proc = Process::new(k.as_raw()).ok()?;
398-
if let Ok(tasks) = proc.tasks() {
399-
for task in tasks.filter_map(Result::ok) {
400-
if task.tid == pid.as_raw() {
401-
parent_pid = Some(*k);
402-
break 'outer;
403-
}
397+
for task in self.event_source.get_tasks(*k) {
398+
if task.tid == pid.as_raw() {
399+
parent_pid = Some(*k);
400+
break 'outer;
404401
}
405402
}
406403
}
407404
if parent_pid.is_none() {
408-
let proc = Process::new(pid.as_raw()).ok()?;
409-
if let Ok(status) = proc.status() {
410-
info!("Found potential parent");
411-
let pid = Pid::from_raw(status.ppid);
412-
parent_pid = Some(pid);
413-
}
405+
parent_pid = self.event_source.get_ppid(pid);
414406
}
415407
parent_pid
416408
})

0 commit comments

Comments
 (0)