WIP(ptrace): Add test for singlesteps
This commit is contained in:
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -4,6 +4,7 @@
|
|||||||
name = "acid"
|
name = "acid"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"redox_syscall 0.1.54 (git+https://gitlab.redox-os.org/jD91mZM2/syscall.git?branch=ptrace)",
|
||||||
"x86 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"x86 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -201,6 +202,11 @@ dependencies = [
|
|||||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.1.54"
|
||||||
|
source = "git+https://gitlab.redox-os.org/jD91mZM2/syscall.git?branch=ptrace#a7aff4b60d537e6f336ff7e8affe8801a92c20f0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-serialize"
|
name = "rustc-serialize"
|
||||||
version = "0.3.24"
|
version = "0.3.24"
|
||||||
@@ -284,6 +290,7 @@ dependencies = [
|
|||||||
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
|
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
|
||||||
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
|
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
|
||||||
"checksum raw-cpuid 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13b844e4049605ff38fed943f5c7b2c691fad68d9d5bf074d2720554c4e48246"
|
"checksum raw-cpuid 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13b844e4049605ff38fed943f5c7b2c691fad68d9d5bf074d2720554c4e48246"
|
||||||
|
"checksum redox_syscall 0.1.54 (git+https://gitlab.redox-os.org/jD91mZM2/syscall.git?branch=ptrace)" = "<none>"
|
||||||
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||||
"checksum serde 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97b18e9e53de541f11e497357d6c5eaeb39f0cb9c8734e274abe4935f6991fa"
|
"checksum serde 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97b18e9e53de541f11e497357d6c5eaeb39f0cb9c8734e274abe4935f6991fa"
|
||||||
"checksum serde_json 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5aaee47e038bf9552d30380d3973fff2593ee0a76d81ad4c581f267cdcadf36"
|
"checksum serde_json 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5aaee47e038bf9552d30380d3973fff2593ee0a76d81ad4c581f267cdcadf36"
|
||||||
|
|||||||
@@ -5,3 +5,4 @@ authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
x86 = "0.7"
|
x86 = "0.7"
|
||||||
|
redox_syscall = { git = "https://gitlab.redox-os.org/jD91mZM2/syscall.git", branch = "ptrace" }
|
||||||
|
|||||||
80
src/main.rs
80
src/main.rs
@@ -1,5 +1,5 @@
|
|||||||
//!Acid testing program
|
//!Acid testing program
|
||||||
#![feature(thread_local)]
|
#![feature(thread_local, asm)]
|
||||||
|
|
||||||
extern crate x86;
|
extern crate x86;
|
||||||
|
|
||||||
@@ -51,6 +51,83 @@ fn page_fault_test() -> Result<(), String> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ptrace() -> Result<(), String> {
|
||||||
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::prelude::*,
|
||||||
|
os::{raw::c_int, unix::io::{AsRawFd, FromRawFd}}
|
||||||
|
};
|
||||||
|
|
||||||
|
let pid = unsafe { syscall::clone(0).map_err(|e| format!("clone failed: {}", e))? };
|
||||||
|
if pid == 0 {
|
||||||
|
unsafe {
|
||||||
|
asm!("
|
||||||
|
mov rax, 20 // GETPID
|
||||||
|
syscall
|
||||||
|
|
||||||
|
mov rdi, rax
|
||||||
|
|
||||||
|
mov rax, 37 // SYS_KILL
|
||||||
|
mov rsi, 19 // SIGSTOP
|
||||||
|
syscall
|
||||||
|
|
||||||
|
// Start of body
|
||||||
|
mov rax, 1
|
||||||
|
push rax
|
||||||
|
mov rax, 2
|
||||||
|
push rax
|
||||||
|
mov rax, 3
|
||||||
|
pop rax
|
||||||
|
pop rax
|
||||||
|
// End of body
|
||||||
|
|
||||||
|
mov rax, 1 // SYS_EXIT
|
||||||
|
mov rdi, 0
|
||||||
|
syscall
|
||||||
|
"
|
||||||
|
: : : : "intel", "volatile"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until child is ready to be traced
|
||||||
|
let mut status = 0;
|
||||||
|
syscall::waitpid(pid, &mut status, syscall::WUNTRACED).map_err(|e| format!("waitpid failed: {}", e))?;
|
||||||
|
|
||||||
|
// Stop & attach process + get handle to registers
|
||||||
|
let mut proc_file = File::open(format!("proc:{}/trace", pid)).map_err(|e| format!("open failed: {}", e))?;
|
||||||
|
let mut regs_file = unsafe {
|
||||||
|
File::from_raw_fd(
|
||||||
|
syscall::dup(proc_file.as_raw_fd() as usize, b"regs/int")
|
||||||
|
.map_err(|e| format!("dup failed: {}", e))? as c_int
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Schedule restart of process when resumed
|
||||||
|
syscall::kill(pid, syscall::SIGCONT).map_err(|e| format!("kill failed: {}", e))?;
|
||||||
|
|
||||||
|
let mut next = move |op| -> Result<syscall::IntRegisters, String> {
|
||||||
|
proc_file.write(&[op]).map_err(|e| format!("ptrace operation failed: {}", e))?;
|
||||||
|
|
||||||
|
let mut regs: syscall::IntRegisters = syscall::IntRegisters::default();
|
||||||
|
regs_file.read(&mut regs).map_err(|e| format!("reading registers failed: {}", e))?;
|
||||||
|
Ok(regs)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Step out of syscall down to the next instruction
|
||||||
|
let _ = next(syscall::PTRACE_SINGLESTEP)?;
|
||||||
|
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 1);
|
||||||
|
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 2);
|
||||||
|
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 2);
|
||||||
|
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 3);
|
||||||
|
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 2);
|
||||||
|
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 1);
|
||||||
|
|
||||||
|
assert_eq!(next(syscall::PTRACE_SYSCALL)?.rax, syscall::SYS_EXIT);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn switch_test() -> Result<(), String> {
|
fn switch_test() -> Result<(), String> {
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use x86::time::rdtscp;
|
use x86::time::rdtscp;
|
||||||
@@ -181,6 +258,7 @@ fn main() {
|
|||||||
let mut tests: BTreeMap<&'static str, fn() -> Result<(), String>> = BTreeMap::new();
|
let mut tests: BTreeMap<&'static str, fn() -> Result<(), String>> = BTreeMap::new();
|
||||||
tests.insert("create_test", create_test);
|
tests.insert("create_test", create_test);
|
||||||
tests.insert("page_fault", page_fault_test);
|
tests.insert("page_fault", page_fault_test);
|
||||||
|
tests.insert("ptrace", ptrace);
|
||||||
tests.insert("switch", switch_test);
|
tests.insert("switch", switch_test);
|
||||||
tests.insert("tcp_fin", tcp_fin_test);
|
tests.insert("tcp_fin", tcp_fin_test);
|
||||||
tests.insert("thread", thread_test);
|
tests.insert("thread", thread_test);
|
||||||
|
|||||||
Reference in New Issue
Block a user