Added syscall and options to custom ptrace wrapper
This commit is contained in:
parent
c7bf8c341c
commit
77a7197718
|
|
@ -36,6 +36,7 @@ dependencies = [
|
|||
name = "bdb"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"color-eyre",
|
||||
"derive_more",
|
||||
"either",
|
||||
|
|
@ -46,9 +47,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.0"
|
||||
version = "2.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ color-eyre = "0.6.3"
|
|||
either = "1.15.0"
|
||||
libc = "0.2.172"
|
||||
derive_more = { version = "2.0.1", features = ["debug"] }
|
||||
bitflags = "2.9.1"
|
||||
|
||||
[build-dependencies]
|
||||
color-eyre = "0.6.3"
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::clibwrap::{CError, Pid};
|
||||
use bitflags::bitflags;
|
||||
use std::ffi::{c_long, c_void};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
|
|
@ -6,6 +7,8 @@ use std::ffi::{c_long, c_void};
|
|||
enum PTraceRequest {
|
||||
PTRACE_CONT = 7,
|
||||
PTRACE_SINGLESTEP = 9,
|
||||
PTRACE_SYSCALL = 24,
|
||||
PTRACE_SETOPTIONS = 0x4200,
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
|
|
@ -29,3 +32,29 @@ pub fn single_step(pid: Pid) -> Result<(), CError> {
|
|||
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}")]
|
||||
pub struct PTraceError(#[from] nix::errno::Errno);
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
#[error(transparent)]
|
||||
pub struct CustomPTraceError(#[from] clibwrap::CError);
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
#[error("Error when waiting on child process: {0}")]
|
||||
pub struct WaitError(#[from] nix::errno::Errno);
|
||||
|
|
@ -20,7 +24,7 @@ pub enum DebugError {
|
|||
PTraceError(#[from] PTraceError),
|
||||
|
||||
#[error(transparent)]
|
||||
CustomPTraceError(#[from] clibwrap::CError),
|
||||
CustomPTraceError(#[from] CustomPTraceError),
|
||||
|
||||
#[error(transparent)]
|
||||
WaitError(#[from] WaitError),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
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 libc::{c_long, user_regs_struct};
|
||||
use nix::sys::wait::{waitid, Id, WaitPidFlag};
|
||||
|
|
@ -22,7 +22,7 @@ impl StoppedTarget {
|
|||
pub fn new(pid: Pid) -> Result<Self, DebugError> {
|
||||
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)
|
||||
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() })
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ impl StoppedTarget {
|
|||
if self.on_breakpoint()? {
|
||||
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())
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ impl StoppedTarget {
|
|||
if self.on_breakpoint()? {
|
||||
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())
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ impl StoppedTarget {
|
|||
if self.on_breakpoint()? {
|
||||
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())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue