From c72af623d099a59146e52c7a03474e06d8a19e90 Mon Sep 17 00:00:00 2001 From: jD91mZM2 Date: Sun, 21 Jul 2019 20:25:16 +0200 Subject: [PATCH] WIP(ptrace): Test new signal behavior --- Cargo.lock | 4 ++-- src/main.rs | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb24363..7aac70f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,7 +206,7 @@ dependencies = [ [[package]] name = "redox_syscall" version = "0.1.56" -source = "git+https://gitlab.redox-os.org/jD91mZM2/syscall.git?branch=ptrace#eddcb80eb7c2d43dedf0ba2ee514b54b0b8fafc7" +source = "git+https://gitlab.redox-os.org/jD91mZM2/syscall.git?branch=ptrace#844650c4fb9725cd9029de6277826bfe0fb19909" [[package]] name = "rustc-serialize" @@ -238,7 +238,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "strace" version = "0.1.0" -source = "git+https://gitlab.redox-os.org/redox-os/strace-redox#b5740938279dbc8334e361d3a8bfc9a4ca64c9ce" +source = "git+https://gitlab.redox-os.org/redox-os/strace-redox#b1ea95f266029e1fc82892c3ce8a10521840135c" dependencies = [ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (git+https://gitlab.redox-os.org/jD91mZM2/syscall.git?branch=ptrace)", diff --git a/src/main.rs b/src/main.rs index eee0891..e7453cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -168,6 +168,10 @@ pub fn ptrace() -> Result<(), String> { mov rsi, 10 // SIGUSR1 syscall + // aaand again + mov rax, 37 // SYS_KILL + syscall + // Test behavior if tracer aborts a breakpoint before it's reached call wait_for_a_while @@ -291,6 +295,7 @@ pub fn ptrace() -> Result<(), String> { PtraceEvent::Clone(pid) => println!("Obtained fork (PID {})", pid), ref e => return Err(format!("Wrong event type: {:?}", e)) } + assert!(e(handler.retry())?.is_none()); println!("Testing fork event - but actually handling the fork"); for _ in 0..3 { // pre-post-waitpid, pre-clone @@ -315,6 +320,7 @@ pub fn ptrace() -> Result<(), String> { }, ref e => return Err(format!("Wrong event type: {:?}", e)) } + assert!(e(handler.retry())?.is_none()); println!("Testing signals"); assert_eq!(e(e(tracer.next(Stop::SYSCALL))?.regs.get_int())?.rax, syscall::SYS_SIGACTION); @@ -323,11 +329,33 @@ pub fn ptrace() -> Result<(), String> { e(tracer.next(Stop::SYSCALL))?; // post-syscall getpid assert_eq!(e(e(tracer.next(Stop::SYSCALL))?.regs.get_int())?.rax, syscall::SYS_KILL); // kill doesn't return *yet* - assert_eq!(e(e(tracer.next(Stop::SYSCALL))?.regs.get_int())?.rax, syscall::SYS_YIELD); - e(tracer.next(Stop::SYSCALL))?; // post-syscall yield - assert_eq!(e(e(tracer.next(Stop::SYSCALL))?.regs.get_int())?.rax, syscall::SYS_SIGRETURN); - // sigreturn doesn't return - e(tracer.next(Stop::SYSCALL))?; // post-syscall kill! + + let mut handler = e(tracer.next_event(Stop::SYSCALL))?.ok_or("Syscall completed without yielding event")?; + let events = e(handler.iter().collect::>>())?; + + assert_eq!(events.len(), 1); + match events[0] { + PtraceEvent::Signal(signal) => { + assert_eq!(signal, syscall::SIGUSR1); + println!("Obtained signal"); + }, + ref e => return Err(format!("Wrong event type: {:?}", e)) + } + + assert!(e(handler.retry())?.is_none()); + for i in 0..2 { + assert_eq!(e(tracer.regs.get_int())?.rax, syscall::SYS_YIELD); + e(tracer.next(Stop::SYSCALL))?; // post-syscall yield + assert_eq!(e(e(tracer.next(Stop::SYSCALL))?.regs.get_int())?.rax, syscall::SYS_SIGRETURN); + // sigreturn doesn't return + e(tracer.next(Stop::SYSCALL))?; // post-syscall kill! + + if i == 0 { + e(tracer.next(Stop::SIGNAL))?; + assert_eq!(e(tracer.regs.get_int())?.rax, syscall::SYS_KILL); + e(tracer.next(Stop::SYSCALL))?; + } + } // Activate nonblock let mut tracer = e(tracer.nonblocking())?; @@ -351,7 +379,7 @@ pub fn ptrace() -> Result<(), String> { println!("Tracee RAX: {}", e(tracer.regs.get_int())?.rax); } - println!("Waiting... Five times. To make sure it doesn't get stuck forever"); + println!("Waiting... Five times... To make sure it doesn't get stuck forever..."); for _ in 0..5 { e(tracer.wait())?; }