Implemented errno in custom clib wrapper

This commit is contained in:
Elnath 2025-05-19 20:17:47 +02:00
parent 77a7197718
commit cc385b7252
3 changed files with 50 additions and 17 deletions

View File

@ -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)
}
}
}

View File

@ -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()) }
}
}

View File

@ -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}")]