Implemented errno in custom clib wrapper
This commit is contained in:
parent
77a7197718
commit
cc385b7252
|
|
@ -1,11 +1,44 @@
|
|||
use std::ffi::c_long;
|
||||
|
||||
use std::ffi::{c_char, c_int, CStr};
|
||||
pub mod ptrace;
|
||||
|
||||
type Pid = i32;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[error("Some kind of error when calling into C code: return code {error_code}")]
|
||||
pub struct CError {
|
||||
error_code: c_long,
|
||||
unsafe extern "C" {
|
||||
fn __errno_location() -> *mut c_int;
|
||||
fn strerror(errnum: c_int) -> *const c_char;
|
||||
fn strerrorname_np(errnum: c_int) -> *const c_char;
|
||||
}
|
||||
|
||||
unsafe fn errno() -> c_int {
|
||||
unsafe { *__errno_location() }
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[error("{}", self.error_message())]
|
||||
pub struct ErrnoError {
|
||||
errno: i32,
|
||||
}
|
||||
|
||||
impl ErrnoError {
|
||||
pub unsafe fn from_current_errno() -> Self {
|
||||
unsafe { Self { errno: errno() } }
|
||||
}
|
||||
|
||||
fn error_message(&self) -> String {
|
||||
unsafe {
|
||||
let error_name = {
|
||||
let c_error_name = strerrorname_np(self.errno);
|
||||
if c_error_name.is_null() {
|
||||
"???"
|
||||
} else {
|
||||
&CStr::from_ptr(c_error_name).to_string_lossy().into_owned()
|
||||
}
|
||||
};
|
||||
let error_message = {
|
||||
let c_str = strerror(self.errno);
|
||||
CStr::from_ptr(c_str).to_string_lossy().into_owned()
|
||||
};
|
||||
format!("{}: {}", error_name, error_message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::clibwrap::{CError, Pid};
|
||||
use crate::clibwrap::{ErrnoError, Pid};
|
||||
use bitflags::bitflags;
|
||||
use std::ffi::{c_long, c_void};
|
||||
|
||||
|
|
@ -15,30 +15,30 @@ unsafe extern "C" {
|
|||
fn ptrace(request: PTraceRequest, pid: Pid, addr: *mut c_void, data: *mut c_void) -> c_long;
|
||||
}
|
||||
|
||||
pub fn cont(pid: Pid) -> Result<(), CError> {
|
||||
pub fn cont(pid: Pid) -> Result<(), ErrnoError> {
|
||||
let return_code = unsafe { ptrace(PTraceRequest::PTRACE_CONT, pid, 0 as _, 0 as _) };
|
||||
if return_code == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(CError { error_code: return_code })
|
||||
unsafe { Err(ErrnoError::from_current_errno()) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn single_step(pid: Pid) -> Result<(), CError> {
|
||||
pub fn single_step(pid: Pid) -> Result<(), ErrnoError> {
|
||||
let return_code = unsafe { ptrace(PTraceRequest::PTRACE_SINGLESTEP, pid, 0 as _, 0 as _) };
|
||||
if return_code == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(CError { error_code: return_code })
|
||||
unsafe { Err(ErrnoError::from_current_errno()) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn syscall(pid: Pid) -> Result<(), CError> {
|
||||
pub fn syscall(pid: Pid) -> Result<(), ErrnoError> {
|
||||
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 })
|
||||
unsafe { Err(ErrnoError::from_current_errno()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -50,11 +50,11 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_options(pid: Pid, options: PTraceOptions) -> Result<(), CError> {
|
||||
pub fn set_options(pid: Pid, options: PTraceOptions) -> Result<(), ErrnoError> {
|
||||
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 })
|
||||
unsafe { Err(ErrnoError::from_current_errno()) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ pub use stopped_target::*;
|
|||
pub struct PTraceError(#[from] nix::errno::Errno);
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
#[error(transparent)]
|
||||
pub struct CustomPTraceError(#[from] clibwrap::CError);
|
||||
#[error("Error when calling ptrace: {0}")]
|
||||
pub struct CustomPTraceError(#[from] clibwrap::ErrnoError);
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
#[error("Error when waiting on child process: {0}")]
|
||||
|
|
|
|||
Loading…
Reference in New Issue