Added syscall and options to custom ptrace wrapper
This commit is contained in:
parent
c7bf8c341c
commit
77a7197718
|
|
@ -36,6 +36,7 @@ dependencies = [
|
||||||
name = "bdb"
|
name = "bdb"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"either",
|
"either",
|
||||||
|
|
@ -46,9 +47,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.9.0"
|
version = "2.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ color-eyre = "0.6.3"
|
||||||
either = "1.15.0"
|
either = "1.15.0"
|
||||||
libc = "0.2.172"
|
libc = "0.2.172"
|
||||||
derive_more = { version = "2.0.1", features = ["debug"] }
|
derive_more = { version = "2.0.1", features = ["debug"] }
|
||||||
|
bitflags = "2.9.1"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
color-eyre = "0.6.3"
|
color-eyre = "0.6.3"
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::clibwrap::{CError, Pid};
|
use crate::clibwrap::{CError, Pid};
|
||||||
|
use bitflags::bitflags;
|
||||||
use std::ffi::{c_long, c_void};
|
use std::ffi::{c_long, c_void};
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
|
@ -6,6 +7,8 @@ use std::ffi::{c_long, c_void};
|
||||||
enum PTraceRequest {
|
enum PTraceRequest {
|
||||||
PTRACE_CONT = 7,
|
PTRACE_CONT = 7,
|
||||||
PTRACE_SINGLESTEP = 9,
|
PTRACE_SINGLESTEP = 9,
|
||||||
|
PTRACE_SYSCALL = 24,
|
||||||
|
PTRACE_SETOPTIONS = 0x4200,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
|
|
@ -29,3 +32,29 @@ pub fn single_step(pid: Pid) -> Result<(), CError> {
|
||||||
Err(CError { error_code: return_code })
|
Err(CError { error_code: return_code })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn syscall(pid: Pid) -> Result<(), CError> {
|
||||||
|
let return_code = unsafe { ptrace(PTraceRequest::PTRACE_SYSCALL, pid, 0 as _, 0 as _) };
|
||||||
|
if return_code == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(CError { error_code: return_code })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PTraceOptions: u32 {
|
||||||
|
const PTRACE_O_TRACESYSGOOD = 1;
|
||||||
|
// Other variants not implemented
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_options(pid: Pid, options: PTraceOptions) -> Result<(), CError> {
|
||||||
|
let return_code = unsafe { ptrace(PTraceRequest::PTRACE_SETOPTIONS, pid, 0 as _, options.bits() as _) };
|
||||||
|
if return_code == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(CError { error_code: return_code })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,10 @@ pub use stopped_target::*;
|
||||||
#[error("Error when calling ptrace: {0}")]
|
#[error("Error when calling ptrace: {0}")]
|
||||||
pub struct PTraceError(#[from] nix::errno::Errno);
|
pub struct PTraceError(#[from] nix::errno::Errno);
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
#[error(transparent)]
|
||||||
|
pub struct CustomPTraceError(#[from] clibwrap::CError);
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
#[error("Error when waiting on child process: {0}")]
|
#[error("Error when waiting on child process: {0}")]
|
||||||
pub struct WaitError(#[from] nix::errno::Errno);
|
pub struct WaitError(#[from] nix::errno::Errno);
|
||||||
|
|
@ -20,7 +24,7 @@ pub enum DebugError {
|
||||||
PTraceError(#[from] PTraceError),
|
PTraceError(#[from] PTraceError),
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
CustomPTraceError(#[from] clibwrap::CError),
|
CustomPTraceError(#[from] CustomPTraceError),
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
WaitError(#[from] WaitError),
|
WaitError(#[from] WaitError),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::clibwrap;
|
use crate::clibwrap;
|
||||||
use crate::debug_target::{DebugError, PTraceError, RunningTarget, WaitError};
|
use crate::debug_target::{CustomPTraceError, DebugError, PTraceError, RunningTarget, WaitError};
|
||||||
use crate::syscall_info::{syscall_info, SyscallInfo, SyscallInfoError};
|
use crate::syscall_info::{syscall_info, SyscallInfo, SyscallInfoError};
|
||||||
use libc::{c_long, user_regs_struct};
|
use libc::{c_long, user_regs_struct};
|
||||||
use nix::sys::wait::{waitid, Id, WaitPidFlag};
|
use nix::sys::wait::{waitid, Id, WaitPidFlag};
|
||||||
|
|
@ -22,7 +22,7 @@ impl StoppedTarget {
|
||||||
pub fn new(pid: Pid) -> Result<Self, DebugError> {
|
pub fn new(pid: Pid) -> Result<Self, DebugError> {
|
||||||
waitid(Id::Pid(pid), WaitPidFlag::WSTOPPED).map_err(WaitError)?;
|
waitid(Id::Pid(pid), WaitPidFlag::WSTOPPED).map_err(WaitError)?;
|
||||||
// Needed for waiting on syscalls and apparently also for getting syscall info (can not get it to work without this)
|
// Needed for waiting on syscalls and apparently also for getting syscall info (can not get it to work without this)
|
||||||
nix::sys::ptrace::setoptions(pid, nix::sys::ptrace::Options::PTRACE_O_TRACESYSGOOD).map_err(PTraceError)?;
|
clibwrap::ptrace::set_options(pid.as_raw(), clibwrap::ptrace::PTraceOptions::PTRACE_O_TRACESYSGOOD).map_err(CustomPTraceError)?;
|
||||||
Ok(Self { pid, breakpoints: HashMap::new() })
|
Ok(Self { pid, breakpoints: HashMap::new() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ impl StoppedTarget {
|
||||||
if self.on_breakpoint()? {
|
if self.on_breakpoint()? {
|
||||||
self.breakpoint_remove_and_rewind()?;
|
self.breakpoint_remove_and_rewind()?;
|
||||||
}
|
}
|
||||||
clibwrap::ptrace::cont(self.pid.as_raw())?;
|
clibwrap::ptrace::cont(self.pid.as_raw()).map_err(CustomPTraceError)?;
|
||||||
Ok(self.to_running())
|
Ok(self.to_running())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ impl StoppedTarget {
|
||||||
if self.on_breakpoint()? {
|
if self.on_breakpoint()? {
|
||||||
self.breakpoint_remove_and_rewind()?;
|
self.breakpoint_remove_and_rewind()?;
|
||||||
}
|
}
|
||||||
clibwrap::ptrace::single_step(self.pid.as_raw())?;
|
clibwrap::ptrace::single_step(self.pid.as_raw()).map_err(CustomPTraceError)?;
|
||||||
Ok(self.to_running())
|
Ok(self.to_running())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,7 +59,7 @@ impl StoppedTarget {
|
||||||
if self.on_breakpoint()? {
|
if self.on_breakpoint()? {
|
||||||
self.breakpoint_remove_and_rewind()?;
|
self.breakpoint_remove_and_rewind()?;
|
||||||
}
|
}
|
||||||
nix::sys::ptrace::syscall(self.pid, None).map_err(PTraceError)?;
|
clibwrap::ptrace::syscall(self.pid.as_raw()).map_err(CustomPTraceError)?;
|
||||||
Ok(self.to_running())
|
Ok(self.to_running())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue