mirror of
https://github.com/urbit/ares.git
synced 2024-11-26 09:57:56 +03:00
Merge branch 'as/serf-guard' into msl/guard
- manual - compiles - tests fail - doesn't run
This commit is contained in:
parent
42ffde2208
commit
1df75a2cab
10
rust/ares/Cargo.lock
generated
10
rust/ares/Cargo.lock
generated
@ -62,7 +62,7 @@ dependencies = [
|
|||||||
"ares_guard",
|
"ares_guard",
|
||||||
"ares_macros",
|
"ares_macros",
|
||||||
"ares_pma",
|
"ares_pma",
|
||||||
"assert_no_alloc 1.1.2",
|
"assert_no_alloc",
|
||||||
"autotools",
|
"autotools",
|
||||||
"bitvec",
|
"bitvec",
|
||||||
"cc",
|
"cc",
|
||||||
@ -87,7 +87,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"aes-siv",
|
"aes-siv",
|
||||||
"assert_no_alloc 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"assert_no_alloc",
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
"ibig 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ibig 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -124,12 +124,6 @@ dependencies = [
|
|||||||
name = "assert_no_alloc"
|
name = "assert_no_alloc"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "assert_no_alloc"
|
|
||||||
version = "1.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "55ca83137a482d61d916ceb1eba52a684f98004f18e0cafea230fe5579c178a3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
|
@ -18,8 +18,8 @@ ares_macros = { path = "../ares_macros" }
|
|||||||
# ares_pma = { path = "../ares_pma", features=["debug_prints"] }
|
# ares_pma = { path = "../ares_pma", features=["debug_prints"] }
|
||||||
ares_pma = { path = "../ares_pma" }
|
ares_pma = { path = "../ares_pma" }
|
||||||
# use this when debugging requires allocation (e.g. eprintln)
|
# use this when debugging requires allocation (e.g. eprintln)
|
||||||
# assert_no_alloc = { path = "../assert-no-alloc", features=["warn_debug"] }
|
# assert_no_alloc = { path = "../rust-assert-no-alloc", features=["warn_debug"] }
|
||||||
assert_no_alloc = { path = "../assert-no-alloc" }
|
assert_no_alloc = { path = "../rust-assert-no-alloc" }
|
||||||
bitvec = "1.0.0"
|
bitvec = "1.0.0"
|
||||||
criterion = "0.4"
|
criterion = "0.4"
|
||||||
either = "1.9.0"
|
either = "1.9.0"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,3 @@
|
|||||||
use crate::guard::call_with_guard;
|
|
||||||
use crate::hamt::Hamt;
|
use crate::hamt::Hamt;
|
||||||
use crate::interpreter;
|
use crate::interpreter;
|
||||||
use crate::interpreter::{inc, interpret, Error, Mote};
|
use crate::interpreter::{inc, interpret, Error, Mote};
|
||||||
@ -403,27 +402,7 @@ fn slam(context: &mut Context, axis: u64, ovo: Noun) -> Result<Noun, Error> {
|
|||||||
let fol = T(stack, &[D(8), pul, D(9), D(2), D(10), sam, D(0), D(2)]);
|
let fol = T(stack, &[D(8), pul, D(9), D(2), D(10), sam, D(0), D(2)]);
|
||||||
let sub = T(stack, &[arvo, ovo]);
|
let sub = T(stack, &[arvo, ovo]);
|
||||||
|
|
||||||
let frame_p = stack.get_frame_pointer();
|
interpret(&mut context.nock_context, sub, fol)
|
||||||
let stack_pp = stack.get_stack_pointer_pointer();
|
|
||||||
let alloc_pp = stack.get_alloc_pointer_pointer();
|
|
||||||
|
|
||||||
let res = call_with_guard(
|
|
||||||
stack_pp as *const *const u64,
|
|
||||||
alloc_pp as *const *const u64,
|
|
||||||
&mut || interpret(&mut context.nock_context, sub, fol),
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Err(Error::NonDeterministic(Mote::Meme, _)) = res {
|
|
||||||
unsafe {
|
|
||||||
let stack = &mut context.nock_context.stack;
|
|
||||||
assert_no_alloc::reset_counters();
|
|
||||||
while stack.get_frame_pointer() != frame_p {
|
|
||||||
stack.frame_pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peek(context: &mut Context, ovo: Noun) -> Noun {
|
fn peek(context: &mut Context, ovo: Noun) -> Noun {
|
||||||
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# use this when debugging requires allocation (e.g. eprintln)
|
# use this when debugging requires allocation (e.g. eprintln)
|
||||||
# assert_no_alloc = {version="1.1.2", features=["warn_debug"]}
|
# assert_no_alloc = { path = "../rust-assert-no-alloc", features=["warn_debug"] }
|
||||||
assert_no_alloc = "1.1.2"
|
assert_no_alloc = { path = "../rust-assert-no-alloc" }
|
||||||
ibig = "0.3.6"
|
ibig = "0.3.6"
|
||||||
|
|
||||||
# ed25519
|
# ed25519
|
||||||
|
@ -15,19 +15,11 @@
|
|||||||
#define GD_PAGE_MASK (GD_PAGE_SIZE - 1)
|
#define GD_PAGE_MASK (GD_PAGE_SIZE - 1)
|
||||||
#define GD_PAGE_ROUND_DOWN(foo) (foo & (~GD_PAGE_MASK))
|
#define GD_PAGE_ROUND_DOWN(foo) (foo & (~GD_PAGE_MASK))
|
||||||
|
|
||||||
/**
|
static uintptr_t guard_p;
|
||||||
* XX: documentation
|
static const uintptr_t *stack_pp;
|
||||||
*/
|
static const uintptr_t *alloc_pp;
|
||||||
typedef struct _gs {
|
static jmp_buf env_buffer;
|
||||||
uintptr_t guard_p;
|
static struct sigaction prev_sa;
|
||||||
const uintptr_t *stack_pp;
|
|
||||||
const uintptr_t *alloc_pp;
|
|
||||||
jmp_buf env_buffer;
|
|
||||||
struct sigaction prev_sa;
|
|
||||||
} GuardState;
|
|
||||||
|
|
||||||
static GuardState *_guard_state = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
static int32_t
|
static int32_t
|
||||||
_prot_page(void *address, int prot)
|
_prot_page(void *address, int prot)
|
||||||
@ -53,18 +45,21 @@ _unmark_page(void *address)
|
|||||||
return _prot_page(address, PROT_READ | PROT_WRITE);
|
return _prot_page(address, PROT_READ | PROT_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Center the guard page.
|
||||||
* Center the guard page.
|
// XX: could be a false positive if the new frame results in exact same guard page
|
||||||
*/
|
// solution: we only re-center from the signal handler
|
||||||
static int32_t
|
static int32_t
|
||||||
_focus_guard(
|
_focus_guard()
|
||||||
uintptr_t *guard_pp,
|
{
|
||||||
const uintptr_t stack_p,
|
uintptr_t stack_p = *stack_pp;
|
||||||
const uintptr_t alloc_p
|
uintptr_t alloc_p = *alloc_pp;
|
||||||
) {
|
uintptr_t old_guard_p = guard_p;
|
||||||
// Check for strange situations.
|
uintptr_t new_guard_p;
|
||||||
|
int32_t err = 0;
|
||||||
|
|
||||||
fprintf(stderr, "guard: focus: stack pointer at %p\r\n", (void *)stack_p);
|
fprintf(stderr, "guard: focus: stack pointer at %p\r\n", (void *)stack_p);
|
||||||
fprintf(stderr, "guard: focus: alloc pointer at %p\r\n", (void *)alloc_p);
|
fprintf(stderr, "guard: focus: alloc pointer at %p\r\n", (void *)alloc_p);
|
||||||
|
|
||||||
if (stack_p == 0 || alloc_p == 0) {
|
if (stack_p == 0 || alloc_p == 0) {
|
||||||
fprintf(stderr, "guard: focus: stack or alloc pointer is null\r\n");
|
fprintf(stderr, "guard: focus: stack or alloc pointer is null\r\n");
|
||||||
return guard_null;
|
return guard_null;
|
||||||
@ -73,20 +68,8 @@ _focus_guard(
|
|||||||
return guard_oom;
|
return guard_oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t old_guard_p = *guard_pp;
|
|
||||||
uintptr_t new_guard_p;
|
|
||||||
int32_t err = 0;
|
|
||||||
|
|
||||||
fprintf(stderr, "guard: focus: old guard = %p\r\n", (void *)old_guard_p);
|
fprintf(stderr, "guard: focus: old guard = %p\r\n", (void *)old_guard_p);
|
||||||
|
|
||||||
// Unmark the old guard page (if there is one)
|
|
||||||
if (old_guard_p) {
|
|
||||||
if ((err = _unmark_page((void *)old_guard_p))) {
|
|
||||||
fprintf(stderr, "guard: focus: unmark error\r\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute new guard page
|
// Compute new guard page
|
||||||
// XX: Should we also check for new_guard_p < min(stack_p, alloc_p)?
|
// XX: Should we also check for new_guard_p < min(stack_p, alloc_p)?
|
||||||
new_guard_p = GD_PAGE_ROUND_DOWN((stack_p + alloc_p) / 2);
|
new_guard_p = GD_PAGE_ROUND_DOWN((stack_p + alloc_p) / 2);
|
||||||
@ -104,45 +87,50 @@ _focus_guard(
|
|||||||
|
|
||||||
// Update guard page tracker
|
// Update guard page tracker
|
||||||
fprintf(stderr, "guard: focus: installed guard page at %p\r\n", (void *)new_guard_p);
|
fprintf(stderr, "guard: focus: installed guard page at %p\r\n", (void *)new_guard_p);
|
||||||
*guard_pp = new_guard_p;
|
guard_p = new_guard_p;
|
||||||
|
|
||||||
|
// Unmark the old guard page (if there is one)
|
||||||
|
if (old_guard_p) {
|
||||||
|
if ((err = _unmark_page((void *)old_guard_p))) {
|
||||||
|
fprintf(stderr, "guard: focus: unmark error\r\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
_signal_handler(int sig, siginfo_t *si, void *unused)
|
_signal_handler(int sig, siginfo_t *si, void *unused)
|
||||||
{
|
{
|
||||||
uintptr_t sig_addr;
|
uintptr_t sig_addr;
|
||||||
int32_t err = 0;
|
int32_t err = 0;
|
||||||
|
|
||||||
|
assert(guard_p);
|
||||||
|
|
||||||
fprintf(stderr, "guard: sig_handle: %d received\r\n", sig);
|
fprintf(stderr, "guard: sig_handle: %d received\r\n", sig);
|
||||||
|
|
||||||
if (sig != SIGSEGV) {
|
if (sig != SIGSEGV) {
|
||||||
fprintf(stderr, "guard: sig_handle: invalid signal\r\n");
|
fprintf(stderr, "guard: sig_handle: invalid signal\r\n");
|
||||||
siglongjmp(_guard_state->env_buffer, guard_signal);
|
// XX: do we even want to jump? if this is fatal error, maybe just die now
|
||||||
|
siglongjmp(env_buffer, guard_signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
sig_addr = (uintptr_t)si->si_addr;
|
sig_addr = (uintptr_t)si->si_addr;
|
||||||
fprintf(stderr, "guard: SIGSEGV address = %p\r\n", (void *)sig_addr);
|
fprintf(stderr, "guard: SIGSEGV address = %p\r\n", (void *)sig_addr);
|
||||||
|
|
||||||
fprintf(stderr, "guard: sig_handle: %p \r\n", _guard_state);
|
if (sig_addr >= guard_p &&
|
||||||
if (
|
sig_addr < guard_p + GD_PAGE_SIZE)
|
||||||
sig_addr >= _guard_state->guard_p &&
|
|
||||||
sig_addr < (_guard_state->guard_p + GD_PAGE_SIZE))
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "guard: page at %p hit\r\n", (void *)_guard_state->guard_p);
|
fprintf(stderr, "guard: hit: %p\r\n", si->si_addr);
|
||||||
err = _focus_guard(
|
err = _focus_guard();
|
||||||
&(_guard_state->guard_p),
|
|
||||||
*(_guard_state->stack_pp),
|
|
||||||
*(_guard_state->alloc_pp));
|
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "guard: sig_handle: focus error\r\n");
|
fprintf(stderr, "guard: sig_handle: focus error\r\n");
|
||||||
siglongjmp(_guard_state->env_buffer, err);
|
siglongjmp(env_buffer, err);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
struct sigaction prev_sa = _guard_state->prev_sa;
|
else {
|
||||||
|
fprintf(stderr, "guard: page at %p miss\r\n", (void *)guard_p);
|
||||||
fprintf(stderr, "guard: page at %p miss\r\n", (void *)_guard_state->guard_p);
|
|
||||||
|
|
||||||
if (prev_sa.sa_sigaction != NULL) {
|
if (prev_sa.sa_sigaction != NULL) {
|
||||||
prev_sa.sa_sigaction(sig, si, unused);
|
prev_sa.sa_sigaction(sig, si, unused);
|
||||||
@ -155,8 +143,8 @@ _signal_handler(int sig, siginfo_t *si, void *unused)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
static int32_t
|
||||||
_register_handler(struct sigaction *prev_sa)
|
_register_handler()
|
||||||
{
|
{
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
|
||||||
@ -171,8 +159,8 @@ _register_handler(struct sigaction *prev_sa)
|
|||||||
// sigemptyset(&sa.sa_mask);
|
// sigemptyset(&sa.sa_mask);
|
||||||
// sigaddset(&(sa.sa_mask), SIGSEGV);
|
// sigaddset(&(sa.sa_mask), SIGSEGV);
|
||||||
|
|
||||||
// Set the new SIGSEGV handler, and save the old SIGSEGV handler (if any)
|
// XX: should assert that prev_sa doesn't have a handler in it, but it's not a pointer so non-trivial
|
||||||
if (sigaction(SIGSEGV, &sa, prev_sa)) {
|
if (sigaction(SIGSEGV, &sa, &prev_sa)) {
|
||||||
fprintf(stderr, "guard: register: sigaction error\r\n");
|
fprintf(stderr, "guard: register: sigaction error\r\n");
|
||||||
fprintf(stderr, "%s\r\n", strerror(errno));
|
fprintf(stderr, "%s\r\n", strerror(errno));
|
||||||
return guard_sigaction | errno;
|
return guard_sigaction | errno;
|
||||||
@ -181,107 +169,59 @@ _register_handler(struct sigaction *prev_sa)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
|
||||||
_setup(
|
|
||||||
GuardState **gs_p,
|
|
||||||
const uintptr_t *const stack_pp,
|
|
||||||
const uintptr_t *const alloc_pp
|
|
||||||
) {
|
|
||||||
GuardState *gs;
|
|
||||||
int32_t err = 0;
|
|
||||||
|
|
||||||
assert(*gs_p == NULL);
|
|
||||||
fprintf(stderr, "guard: setup: stack pointer at %p\r\n", (void *)(*stack_pp));
|
|
||||||
fprintf(stderr, "guard: setup: alloc pointer at %p\r\n", (void *)(*alloc_pp));
|
|
||||||
|
|
||||||
// Setup guard page state
|
|
||||||
*gs_p = (GuardState *)malloc(sizeof(GuardState));
|
|
||||||
gs = *gs_p;
|
|
||||||
if (gs == NULL) {
|
|
||||||
fprintf(stderr, "guard: malloc error\r\n");
|
|
||||||
fprintf(stderr, "%s\r\n", strerror(errno));
|
|
||||||
return guard_malloc | errno;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "guard: state allocated to %p \r\n", gs);
|
|
||||||
|
|
||||||
gs->guard_p = 0;
|
|
||||||
gs->stack_pp = stack_pp;
|
|
||||||
gs->alloc_pp = alloc_pp;
|
|
||||||
|
|
||||||
// Initialize the guard page
|
|
||||||
if ((err = _focus_guard(&(gs->guard_p), *stack_pp, *alloc_pp))) {
|
|
||||||
fprintf(stderr, "guard: setup: _focus_guard error\r\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register guard page signal handler
|
|
||||||
if ((err = _register_handler(&(gs->prev_sa)))) {
|
|
||||||
fprintf(stderr, "guard: setup: _register_handler error\r\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t
|
|
||||||
_teardown(GuardState** gs_p)
|
|
||||||
{
|
|
||||||
int32_t err = 0;
|
|
||||||
|
|
||||||
if (*gs_p != NULL) {
|
|
||||||
GuardState *gs = *gs_p;
|
|
||||||
|
|
||||||
if (gs->guard_p != 0) {
|
|
||||||
err = _unmark_page((void *)gs->guard_p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sigaction(SIGSEGV, &(gs->prev_sa), NULL)) {
|
|
||||||
fprintf(stderr, "guard: teardown: sigaction error\r\n");
|
|
||||||
fprintf(stderr, "%s\r\n", strerror(errno));
|
|
||||||
err = guard_sigaction | errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(gs);
|
|
||||||
*gs_p = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
guard(
|
guard(
|
||||||
callback f,
|
callback f,
|
||||||
void *closure,
|
void *closure,
|
||||||
const uintptr_t *const stack_pp,
|
const uintptr_t *const s_pp,
|
||||||
const uintptr_t *const alloc_pp,
|
const uintptr_t *const a_pp,
|
||||||
void ** ret
|
void ** ret
|
||||||
) {
|
) {
|
||||||
int32_t err = 0;
|
int32_t err = 0;
|
||||||
|
int32_t td_err;
|
||||||
|
|
||||||
// Setup the guard page
|
assert(guard_p == 0);
|
||||||
fprintf(stderr, "guard: setup\r\n");
|
fprintf(stderr, "guard: setup: stack pointer at %p\r\n", (void *)(*stack_pp));
|
||||||
if ((err = _setup(&_guard_state, stack_pp, alloc_pp))) {
|
fprintf(stderr, "guard: setup: alloc pointer at %p\r\n", (void *)(*alloc_pp));
|
||||||
|
|
||||||
|
guard_p = 0;
|
||||||
|
stack_pp = s_pp;
|
||||||
|
alloc_pp = a_pp;
|
||||||
|
|
||||||
|
// Initialize the guard page
|
||||||
|
if ((err = _focus_guard())) {
|
||||||
|
fprintf(stderr, "guard: setup: _focus_guard error\r\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register guard page signal handler
|
||||||
|
if ((err = _register_handler())) {
|
||||||
|
fprintf(stderr, "guard: setup: _register_handler error\r\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run given closure
|
// Run given closure
|
||||||
fprintf(stderr, "guard: run\r\n");
|
fprintf(stderr, "guard: run\r\n");
|
||||||
if (!(err = sigsetjmp(_guard_state->env_buffer, 1))) {
|
if (!(err = sigsetjmp(env_buffer, 1))) {
|
||||||
*ret = f(closure);
|
*ret = f(closure);
|
||||||
|
|
||||||
// Clean up
|
|
||||||
fprintf(stderr, "guard: teardown\r\n");
|
|
||||||
err = _teardown(&_guard_state);
|
|
||||||
|
|
||||||
fprintf(stderr, "guard: return\r\n");
|
|
||||||
return err;
|
|
||||||
} else {
|
|
||||||
done:
|
|
||||||
// Clean up
|
|
||||||
fprintf(stderr, "guard: teardown\r\n");
|
|
||||||
_teardown(&_guard_state);
|
|
||||||
|
|
||||||
fprintf(stderr, "guard: return\r\n");
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
// Clean up
|
||||||
|
if (guard_p != 0) {
|
||||||
|
td_err = _unmark_page((void *)guard_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sigaction(SIGSEGV, &prev_sa, NULL)) {
|
||||||
|
fprintf(stderr, "guard: teardown: sigaction error\r\n");
|
||||||
|
fprintf(stderr, "%s\r\n", strerror(errno));
|
||||||
|
td_err = guard_sigaction | errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
err = td_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "guard: return\r\n");
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Error codes and flags.
|
* Error codes and flags.
|
||||||
*
|
*
|
||||||
* The flags are bitwise added to the errno of their respective errors.
|
* The flags are bitwise added to the errno of their respective errors.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -51,9 +51,9 @@ int32_t
|
|||||||
guard(
|
guard(
|
||||||
callback f,
|
callback f,
|
||||||
void *closure,
|
void *closure,
|
||||||
const uintptr_t *const stack_pp,
|
const uintptr_t *const s_pp,
|
||||||
const uintptr_t *const alloc_pp,
|
const uintptr_t *const a_pp,
|
||||||
void ** ret
|
void **ret
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif // __GUARD_H__
|
#endif // __GUARD_H__
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||||
|
|
||||||
pub const GUARD_NULL: u32 = guard_err_guard_null;
|
pub const GUARD_NULL: u32 = guard_err_guard_null;
|
||||||
pub const GUARD_SIGNAL: u32 = guard_err_guard_signal;
|
pub const GUARD_SIGNAL: u32 = guard_err_guard_signal;
|
||||||
pub const GUARD_OOM: u32 = guard_err_guard_oom;
|
pub const GUARD_OOM: u32 = guard_err_guard_oom;
|
||||||
pub const GUARD_MALLOC: u32 = guard_err_guard_malloc;
|
pub const GUARD_MALLOC: u32 = guard_err_guard_malloc;
|
||||||
pub const GUARD_MPROTECT: u32 = guard_err_guard_mprotect;
|
pub const GUARD_MPROTECT: u32 = guard_err_guard_mprotect;
|
||||||
|
@ -1567,6 +1567,7 @@ _flist_grow(BT_state *state, size_t pages)
|
|||||||
/* grows the backing file by PMA_GROW_SIZE_p and appends this freespace to the
|
/* grows the backing file by PMA_GROW_SIZE_p and appends this freespace to the
|
||||||
flist */
|
flist */
|
||||||
{
|
{
|
||||||
|
exit(1);
|
||||||
/* grow the backing file by at least PMA_GROW_SIZE_p */
|
/* grow the backing file by at least PMA_GROW_SIZE_p */
|
||||||
pages = MAX(pages, PMA_GROW_SIZE_p);
|
pages = MAX(pages, PMA_GROW_SIZE_p);
|
||||||
off_t bytes = P2BYTES(pages);
|
off_t bytes = P2BYTES(pages);
|
||||||
|
@ -91,6 +91,23 @@ pub fn assert_no_alloc<T, F: FnOnce() -> T> (func: F) -> T {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(all(feature = "disable_release", not(debug_assertions))))] // if not disabled
|
||||||
|
/// Calls the `func` closure, but ensures that the forbid and permit counters
|
||||||
|
/// are maintained accurately even if a longjmp originates and terminates
|
||||||
|
/// within the closure. If you longjmp over this function, we can't fix
|
||||||
|
/// anything about it.
|
||||||
|
pub fn ensure_alloc_counters<T, F: FnOnce() -> T> (func: F) -> T {
|
||||||
|
let forbid_counter = ALLOC_FORBID_COUNT.with(|c| c.get());
|
||||||
|
let permit_counter = ALLOC_PERMIT_COUNT.with(|c| c.get());
|
||||||
|
|
||||||
|
let ret = func();
|
||||||
|
|
||||||
|
ALLOC_FORBID_COUNT.with(|c| c.set(forbid_counter));
|
||||||
|
ALLOC_PERMIT_COUNT.with(|c| c.set(permit_counter));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(all(feature = "disable_release", not(debug_assertions))))] // if not disabled
|
#[cfg(not(all(feature = "disable_release", not(debug_assertions))))] // if not disabled
|
||||||
/// Calls the `func` closure. Allocations are temporarily allowed, even if this
|
/// Calls the `func` closure. Allocations are temporarily allowed, even if this
|
||||||
/// code runs inside of assert_no_alloc.
|
/// code runs inside of assert_no_alloc.
|
||||||
@ -142,6 +159,7 @@ pub fn reset_counters() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(not(all(feature = "disable_release", not(debug_assertions))))] // if not disabled
|
#[cfg(not(all(feature = "disable_release", not(debug_assertions))))] // if not disabled
|
||||||
/// The custom allocator that handles the checking.
|
/// The custom allocator that handles the checking.
|
||||||
///
|
///
|
Loading…
Reference in New Issue
Block a user