• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

xd009642 / tarpaulin / #735

17 Mar 2026 03:28AM UTC coverage: 85.243% (-0.3%) from 85.516%
#735

Pull #1830

xd009642
Add process offset as well.
Pull Request #1830: Start abstracting all process things.

95 of 132 new or added lines in 4 files covered. (71.97%)

3 existing lines in 1 file now uncovered.

4835 of 5672 relevant lines covered (85.24%)

246223.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.51
/src/process_handling/event_source.rs
1
use crate::cargo::rust_flags;
2
use crate::config::Config;
3
use crate::statemachine::*;
4
use crate::{errors::RunError, process_handling::ptrace_control::*};
5
use libc::c_long;
6
use nix::{
7
    sys::{
8
        signal::Signal,
9
        wait::{waitpid, WaitPidFlag, WaitStatus},
10
    },
11
    unistd::Pid,
12
};
13
use procfs::process::{MMapPath, Process};
14

15
pub trait EventSource {
16
    fn request_trace(&self) -> nix::Result<()>;
17
    fn get_offset(&self, pid: Pid, config: &Config) -> u64;
18
    fn trace_children(&self, pid: Pid) -> nix::Result<()>;
19
    fn waitpid(&self, pid: Pid, options: Option<WaitPidFlag>) -> nix::Result<WaitStatus>;
20
    fn next_events(&self, wait_queue: &mut Vec<WaitStatus>) -> Result<Option<TestState>, RunError>;
21
    fn get_event_data(&self, pid: Pid) -> nix::Result<c_long>;
22
    fn continue_pid(&self, pid: Pid, signal: Option<Signal>) -> nix::Result<()>;
23
    fn single_step(&self, pid: Pid) -> nix::Result<()>;
24
    fn detach_child(&self, pid: Pid) -> nix::Result<()>;
25
    fn current_instruction_pointer(&self, pid: Pid) -> nix::Result<c_long>;
26
    fn set_current_instruction_pointer(&self, pid: Pid, addr: u64) -> nix::Result<c_long>;
27
    fn write_address(&self, pid: Pid, addr: u64, data: c_long) -> nix::Result<()>;
28
    fn read_address(&self, pid: Pid, addr: u64) -> nix::Result<c_long>;
29
}
30

31
#[derive(Clone)]
32
pub struct PtraceEventSource;
33

34
impl EventSource for PtraceEventSource {
NEW
35
    fn request_trace(&self) -> nix::Result<()> {
×
NEW
36
        request_trace()
×
37
    }
38

39
    fn get_offset(&self, pid: Pid, config: &Config) -> u64 {
204✔
40
        // TODO I don't think this would be an issue... but I'll test it
41
        if rust_flags(config, &Default::default()).contains("dynamic-no-pic") {
408✔
NEW
42
            0
×
43
        } else if let Ok(proc) = Process::new(pid.as_raw()) {
612✔
44
            let exe = proc.exe().ok();
816✔
45
            if let Ok(maps) = proc.maps() {
408✔
46
                let offset_info = maps.iter().find(|x| match (&x.pathname, exe.as_ref()) {
1,224✔
47
                    (MMapPath::Path(p), Some(e)) => p == e,
612✔
NEW
48
                    (MMapPath::Path(_), None) => true,
×
NEW
49
                    _ => false,
×
50
                });
51
                if let Some(first) = offset_info {
408✔
52
                    first.address.0
204✔
53
                } else {
NEW
54
                    0
×
55
                }
56
            } else {
NEW
57
                0
×
58
            }
59
        } else {
NEW
60
            0
×
61
        }
62
    }
63

64
    fn trace_children(&self, pid: Pid) -> nix::Result<()> {
204✔
65
        trace_children(pid)
408✔
66
    }
67

68
    fn waitpid(&self, pid: Pid, options: Option<WaitPidFlag>) -> nix::Result<WaitStatus> {
811,620✔
69
        waitpid(pid, options)
2,434,860✔
70
    }
71

72
    fn next_events(&self, wait_queue: &mut Vec<WaitStatus>) -> Result<Option<TestState>, RunError> {
807,376✔
73
        let mut result = Ok(None);
1,614,752✔
74
        let mut running = true;
1,614,752✔
75
        while running {
1,618,806✔
76
            let wait = self.waitpid(
2,434,290✔
77
                Pid::from_raw(-1),
811,430✔
78
                Some(WaitPidFlag::WNOHANG | WaitPidFlag::__WALL),
811,430✔
79
            );
80
            match wait {
811,428✔
81
                Ok(WaitStatus::StillAlive) => {
806,280✔
82
                    running = false;
806,280✔
83
                }
84
                Ok(WaitStatus::Exited(_, _)) => {
430✔
85
                    wait_queue.push(wait.unwrap());
2,150✔
86
                    result = Ok(Some(TestState::Stopped));
860✔
87
                    running = false;
430✔
88
                }
89
                Ok(WaitStatus::PtraceEvent(_, _, _)) => {
664✔
90
                    wait_queue.push(wait.unwrap());
3,320✔
91
                    result = Ok(Some(TestState::Stopped));
1,328✔
92
                    running = false;
664✔
93
                }
94
                Ok(s) => {
8,108✔
95
                    wait_queue.push(s);
16,216✔
96
                    result = Ok(Some(TestState::Stopped));
4,054✔
97
                }
98
                Err(e) => {
4✔
99
                    running = false;
4✔
100
                    result = Err(RunError::TestRuntime(format!(
2✔
101
                        "An error occurred while waiting for response from test: {e}"
2✔
102
                    )));
103
                }
104
            }
105
        }
106
        result
807,376✔
107
    }
108

109
    fn get_event_data(&self, pid: Pid) -> nix::Result<c_long> {
240✔
110
        get_event_data(pid)
480✔
111
    }
112

113
    fn continue_pid(&self, pid: Pid, signal: Option<Signal>) -> nix::Result<()> {
3,434✔
114
        continue_exec(pid, signal)
10,302✔
115
    }
116

117
    fn single_step(&self, pid: Pid) -> nix::Result<()> {
1,904✔
118
        single_step(pid)
3,808✔
119
    }
120

121
    fn detach_child(&self, pid: Pid) -> nix::Result<()> {
2✔
122
        detach_child(pid)
4✔
123
    }
124

125
    fn current_instruction_pointer(&self, pid: Pid) -> nix::Result<c_long> {
3,808✔
126
        current_instruction_pointer(pid)
7,616✔
127
    }
128

129
    fn set_current_instruction_pointer(&self, pid: Pid, addr: u64) -> nix::Result<c_long> {
1,904✔
130
        set_instruction_pointer(pid, addr)
5,712✔
131
    }
132

133
    fn write_address(&self, pid: Pid, address: u64, data: c_long) -> nix::Result<()> {
4,596✔
134
        write_to_address(pid, address, data)
18,384✔
135
    }
136

137
    fn read_address(&self, pid: Pid, address: u64) -> nix::Result<c_long> {
9,228✔
138
        read_address(pid, address)
27,684✔
139
    }
140
}
141

142
#[derive(Clone)]
143
pub struct ReplayEventSource {}
144

145
impl EventSource for ReplayEventSource {
NEW
146
    fn request_trace(&self) -> nix::Result<()> {
×
NEW
147
        Ok(())
×
148
    }
149

NEW
150
    fn get_offset(&self, pid: Pid, config: &Config) -> u64 {
×
NEW
151
        0
×
152
    }
153

NEW
154
    fn trace_children(&self, pid: Pid) -> nix::Result<()> {
×
155
        todo!()
156
    }
157

NEW
158
    fn waitpid(&self, pid: Pid, options: Option<WaitPidFlag>) -> nix::Result<WaitStatus> {
×
159
        todo!()
160
    }
161

NEW
162
    fn next_events(&self, wait_queue: &mut Vec<WaitStatus>) -> Result<Option<TestState>, RunError> {
×
163
        todo!();
164
    }
165

NEW
166
    fn get_event_data(&self, pid: Pid) -> nix::Result<c_long> {
×
167
        todo!()
168
    }
169

NEW
170
    fn continue_pid(&self, pid: Pid, signal: Option<Signal>) -> nix::Result<()> {
×
171
        todo!();
172
    }
173

NEW
174
    fn single_step(&self, pid: Pid) -> nix::Result<()> {
×
175
        todo!();
176
    }
177

NEW
178
    fn detach_child(&self, pid: Pid) -> nix::Result<()> {
×
179
        todo!()
180
    }
181

NEW
182
    fn current_instruction_pointer(&self, pid: Pid) -> nix::Result<c_long> {
×
183
        todo!();
184
    }
185

NEW
186
    fn set_current_instruction_pointer(&self, pid: Pid, addr: u64) -> nix::Result<c_long> {
×
187
        todo!();
188
    }
189

NEW
190
    fn write_address(&self, pid: Pid, address: u64, data: c_long) -> nix::Result<()> {
×
191
        todo!();
192
    }
193

NEW
194
    fn read_address(&self, pid: Pid, address: u64) -> nix::Result<c_long> {
×
195
        todo!();
196
    }
197
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc