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>(
|
pub fn call_with_guard<F: FnMut() -> Result>(
|
||||||
f: F,
|
f: F,
|
||||||
stack: *mut *mut c_void,
|
stack: *const c_void,
|
||||||
alloc: *mut *mut c_void,
|
alloc: *const c_void,
|
||||||
ret: *mut *mut c_void,
|
ret: *mut *mut c_void,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
eprintln!("call_with_guard");
|
|
||||||
let boxed_f = Box::new(f);
|
let boxed_f = Box::new(f);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -988,8 +987,8 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
stack_p as *mut *mut c_void,
|
stack_p as *const c_void,
|
||||||
alloc_p as *mut *mut c_void,
|
alloc_p as *const c_void,
|
||||||
std::ptr::null_mut() as *mut *mut 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() {
|
guard_err _focus_guard() {
|
||||||
// Check for strange situations.
|
// Check for strange situations.
|
||||||
if (stack_p == NULL || alloc_p == NULL) {
|
if (stack_p == NULL || alloc_p == NULL) {
|
||||||
|
fprintf(stderr, "guard: stack or alloc pointer is null\r\n");
|
||||||
return guard_weird;
|
return guard_weird;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmark the old guard page.
|
// Unmark the old guard page.
|
||||||
void *old_guard_p = guard_p;
|
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;
|
return guard_armor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +57,7 @@ guard_err _focus_guard() {
|
|||||||
|
|
||||||
guard_err _slash_guard(void *si_addr) {
|
guard_err _slash_guard(void *si_addr) {
|
||||||
if (si_addr >= guard_p && si_addr < guard_p + GD_PAGESIZE) {
|
if (si_addr >= guard_p && si_addr < guard_p + GD_PAGESIZE) {
|
||||||
|
fprintf(stderr, "guard: slash\r\n");
|
||||||
return _focus_guard();
|
return _focus_guard();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,11 +67,11 @@ guard_err _slash_guard(void *si_addr) {
|
|||||||
void _signal_handler(int sig, siginfo_t *si, void *unused) {
|
void _signal_handler(int sig, siginfo_t *si, void *unused) {
|
||||||
switch (sig) {
|
switch (sig) {
|
||||||
case SIGSEGV:
|
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);
|
err = _slash_guard(si->si_addr);
|
||||||
break;
|
break;
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
fprintf(stderr, "guard: caught sigint\r\n");
|
|
||||||
err = guard_erupt;
|
err = guard_erupt;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -91,19 +93,25 @@ guard_err _register_handler() {
|
|||||||
return guard_sound;
|
return guard_sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
stack_p = *stack;
|
stack_p = stack;
|
||||||
alloc_p = *alloc;
|
alloc_p = alloc;
|
||||||
|
|
||||||
if (_register_handler() != guard_sound) {
|
if (_register_handler() != guard_sound) {
|
||||||
err = guard_weird;
|
err = guard_weird;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "guard: installing guard page\r\n");
|
if (guard_p == NULL) {
|
||||||
if (guard_p == NULL && (err = _focus_guard()) != guard_sound) {
|
fprintf(stderr, "guard: installing guard page\r\n");
|
||||||
goto fail;
|
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);
|
*ret = f(arg);
|
||||||
|
|
||||||
@ -114,6 +122,7 @@ void guard(void *(*f)(void *), void *arg, void *const *const stack, void *const
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
fprintf(stderr, "guard: error %d\r\n", err);
|
||||||
*ret = (void *) &err;
|
*ret = (void *) &err;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
* error will be written to the `ret` pointer. The caller is then responsible
|
* error will be written to the `ret` pointer. The caller is then responsible
|
||||||
* for handling this error and aborting with a `bail:meme`.
|
* 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 {
|
typedef enum {
|
||||||
guard_sound = 0, // job's done
|
guard_sound = 0, // job's done
|
||||||
|
@ -2,4 +2,22 @@
|
|||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
#![allow(non_snake_case)]
|
#![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