mirror of
https://github.com/urbit/ares.git
synced 2024-11-26 09:57:56 +03:00
wip: debugging
This commit is contained in:
parent
43d145ac72
commit
5e44f2f94f
@ -375,11 +375,10 @@ extern "C" fn rust_callback(arg: *mut c_void) -> *mut c_void {
|
||||
|
||||
pub fn call_with_guard<F: FnMut() -> Result>(
|
||||
f: F,
|
||||
stack: *mut *mut c_void,
|
||||
alloc: *mut *mut c_void,
|
||||
stack: *const c_void,
|
||||
alloc: *const c_void,
|
||||
ret: *mut *mut c_void,
|
||||
) -> Result {
|
||||
eprintln!("call_with_guard");
|
||||
let boxed_f = Box::new(f);
|
||||
|
||||
unsafe {
|
||||
@ -988,8 +987,8 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
|
||||
};
|
||||
}
|
||||
},
|
||||
stack_p as *mut *mut c_void,
|
||||
alloc_p as *mut *mut c_void,
|
||||
stack_p as *const c_void,
|
||||
alloc_p as *const c_void,
|
||||
std::ptr::null_mut() as *mut *mut c_void,
|
||||
)
|
||||
})
|
||||
|
@ -21,12 +21,13 @@ volatile sig_atomic_t err = guard_sound;
|
||||
guard_err _focus_guard() {
|
||||
// Check for strange situations.
|
||||
if (stack_p == NULL || alloc_p == NULL) {
|
||||
fprintf(stderr, "guard: stack or alloc pointer is null\r\n");
|
||||
return guard_weird;
|
||||
}
|
||||
|
||||
// Unmark the old guard page.
|
||||
void *old_guard_p = guard_p;
|
||||
if (mprotect(old_guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1) {
|
||||
if (old_guard_p != NULL && mprotect(old_guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1) {
|
||||
return guard_armor;
|
||||
}
|
||||
|
||||
@ -56,6 +57,7 @@ guard_err _focus_guard() {
|
||||
|
||||
guard_err _slash_guard(void *si_addr) {
|
||||
if (si_addr >= guard_p && si_addr < guard_p + GD_PAGESIZE) {
|
||||
fprintf(stderr, "guard: slash\r\n");
|
||||
return _focus_guard();
|
||||
}
|
||||
|
||||
@ -65,11 +67,11 @@ guard_err _slash_guard(void *si_addr) {
|
||||
void _signal_handler(int sig, siginfo_t *si, void *unused) {
|
||||
switch (sig) {
|
||||
case SIGSEGV:
|
||||
fprintf(stderr, "guard: caught sigsegv\r\n");
|
||||
fprintf(stderr, "guard: segfault at %p\r\n", si->si_addr);
|
||||
fprintf(stderr, "guard: guard at %p\r\n", guard_p);
|
||||
err = _slash_guard(si->si_addr);
|
||||
break;
|
||||
case SIGINT:
|
||||
fprintf(stderr, "guard: caught sigint\r\n");
|
||||
err = guard_erupt;
|
||||
break;
|
||||
default:
|
||||
@ -91,19 +93,25 @@ guard_err _register_handler() {
|
||||
return guard_sound;
|
||||
}
|
||||
|
||||
void guard(void *(*f)(void *), void *arg, void *const *const stack, void *const *const alloc, void **ret) {
|
||||
stack_p = *stack;
|
||||
alloc_p = *alloc;
|
||||
void guard(void *(*f)(void *), void *arg, void *const stack, void *const alloc, void **ret) {
|
||||
stack_p = stack;
|
||||
alloc_p = alloc;
|
||||
|
||||
if (_register_handler() != guard_sound) {
|
||||
err = guard_weird;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fprintf(stderr, "guard: installing guard page\r\n");
|
||||
if (guard_p == NULL && (err = _focus_guard()) != guard_sound) {
|
||||
goto fail;
|
||||
if (guard_p == NULL) {
|
||||
fprintf(stderr, "guard: installing guard page\r\n");
|
||||
guard_err install_err = _focus_guard();
|
||||
if (install_err != guard_sound) {
|
||||
fprintf(stderr, "guard: failed to install guard page\r\n");
|
||||
err = install_err;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "guard: guard page installed at %p\r\n", guard_p);
|
||||
|
||||
*ret = f(arg);
|
||||
|
||||
@ -114,6 +122,7 @@ void guard(void *(*f)(void *), void *arg, void *const *const stack, void *const
|
||||
return;
|
||||
|
||||
fail:
|
||||
fprintf(stderr, "guard: error %d\r\n", err);
|
||||
*ret = (void *) &err;
|
||||
return;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
* error will be written to the `ret` pointer. The caller is then responsible
|
||||
* for handling this error and aborting with a `bail:meme`.
|
||||
*/
|
||||
void guard(void *(*f)(void *), void *arg, void *const *const stack, void *const *const alloc, void **ret);
|
||||
void guard(void *(*f)(void *), void *arg, void *const stack, void *const alloc, void **ret);
|
||||
|
||||
typedef enum {
|
||||
guard_sound = 0, // job's done
|
||||
|
@ -2,4 +2,22 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
|
||||
extern "C" {
|
||||
#[doc = " Execute the given closure `f` within the memory arena between the\n `stack` and `alloc` pointers, with guard page protection. Write either\n `f`'s succesful result or a `guard_err` to the given `ret` pointer.\n\n Memory\n ------\n The free memory arena between the `stack` and `alloc` pointers is part of a\n NockStack frame, which may either face east or west. If the frame faces\n east, the `stack` pointer will be greater than the `alloc` pointer. If it\n faces west, the `stack` pointer will be less than the `alloc` pointer.\n\n All the pages in the memory arena are marked clean (`PROT_READ | PROT_WRITE`)\n by default, with the exception of a single guard page in the middle of the\n arena, which is marked with `PROT_NONE`.\n\n Guard\n -----\n This function protects the free memory arena between the `stack` and `alloc`\n pointers with a guard page. A guard page is simply a single page of memory\n which is marked with `PROT_NONE`. Since all other pages are marked clean by\n default, a SIGSEGV will only be raised if the `f` function attempts to write\n to the guard page. When it does, the signal handler will attempt to re-center\n the guard page in the remaining free space left in the arena. If there is no\n more free space, then memory exhaustion has occurred and the `guard_spent`\n error will be written to the `ret` pointer. The caller is then responsible\n for handling this error and aborting with a `bail:meme`."]
|
||||
pub fn guard(
|
||||
f: ::std::option::Option<
|
||||
unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void,
|
||||
>,
|
||||
arg: *mut ::std::os::raw::c_void,
|
||||
stack: *const ::std::os::raw::c_void,
|
||||
alloc: *const ::std::os::raw::c_void,
|
||||
ret: *mut *mut ::std::os::raw::c_void,
|
||||
);
|
||||
}
|
||||
pub const guard_err_guard_sound: guard_err = 0;
|
||||
pub const guard_err_guard_armor: guard_err = 1;
|
||||
pub const guard_err_guard_weird: guard_err = 2;
|
||||
pub const guard_err_guard_spent: guard_err = 3;
|
||||
pub const guard_err_guard_erupt: guard_err = 4;
|
||||
pub type guard_err = ::std::os::raw::c_uint;
|
Loading…
Reference in New Issue
Block a user