Skip to content

Commit

Permalink
Eliminate g_alt_stack variable and void* runtime context
Browse files Browse the repository at this point in the history
(just use OS to keep track of the altstack)
  • Loading branch information
keithw committed Nov 26, 2023
1 parent 0855d21 commit 9cfeb80
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 34 deletions.
4 changes: 2 additions & 2 deletions wasm2c/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ void wasm_rt_allocate_externref_table(wasm_rt_externref_table_t*, uint32_t eleme
void wasm_rt_free_funcref_table(wasm_rt_table_t*);
void wasm_rt_free_externref_table(wasm_rt_table_t*);
uint32_t wasm_rt_call_stack_depth; /* on platforms that don't use the signal handler to detect exhaustion */
void* wasm_rt_init_thread(void);
void wasm_rt_free_thread(void*);
void wasm_rt_init_thread(void);
void wasm_rt_free_thread(void);
```
`wasm_rt_init` must be called by the embedder before anything else, to
Expand Down
4 changes: 2 additions & 2 deletions wasm2c/examples/threads/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ void* do_thread(void* arg) {
/* Initialize the per-thread context for the Wasm runtime (in practice, an
altstack for catching segfaults caused by stack exhaustion or out-of-bounds
memory access. */
void* context = wasm_rt_init_thread();
wasm_rt_init_thread();

/* Instantiate the Wasm module. */
w2c_sample inst;
Expand All @@ -85,7 +85,7 @@ void* do_thread(void* arg) {
wasm2c_sample_free(&inst);

/* Free the per-thread runtime context. */
wasm_rt_free_thread(context);
wasm_rt_free_thread();

return arg;
} else {
Expand Down
41 changes: 16 additions & 25 deletions wasm2c/wasm-rt-impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ static void* g_sig_handler_handle = 0;
#if WASM_RT_USE_STACK_DEPTH_COUNT
WASM_RT_THREAD_LOCAL uint32_t wasm_rt_call_stack_depth;
WASM_RT_THREAD_LOCAL uint32_t wasm_rt_saved_call_stack_depth;
#elif WASM_RT_INSTALL_SIGNAL_HANDLER
static char* g_alt_stack = 0;
#endif

WASM_RT_THREAD_LOCAL wasm_rt_jmp_buf g_wasm_rt_jmp_buf;
Expand Down Expand Up @@ -184,7 +182,7 @@ static bool os_has_altstack_installed() {
}

/* Use alt stack to handle SIGSEGV from stack overflow */
static void* os_allocate_and_install_altstack(void) {
static void os_allocate_and_install_altstack(void) {
/* allocate altstack */
void* alt_stack = malloc(SIGSTKSZ);
if (alt_stack == NULL) {
Expand All @@ -202,7 +200,7 @@ static void* os_allocate_and_install_altstack(void) {
abort();
}

return alt_stack;
/* altstack pointer is stored by OS */
}

static void os_install_signal_handler(void) {
Expand All @@ -223,27 +221,27 @@ static void os_install_signal_handler(void) {
}
}

static void os_disable_and_deallocate_altstack(void* alt_stack) {
static void os_disable_and_deallocate_altstack(void) {
/* verify altstack was still in place */
stack_t ss;
if (sigaltstack(NULL, &ss) != 0) {
perror("sigaltstack failed");
abort();
}
if (!(ss.ss_flags & SS_DISABLE) && (ss.ss_sp == alt_stack) &&
(ss.ss_size == SIGSTKSZ)) {
/* disable */
if (!(ss.ss_flags & SS_DISABLE) && (ss.ss_size == SIGSTKSZ)) {
/* disable and free */
void* alt_stack = ss.ss_sp;
ss.ss_flags = SS_DISABLE;
if (sigaltstack(&ss, NULL) != 0) {
perror("sigaltstack failed");
abort();
}
assert(!os_has_altstack_installed());
} else {
fprintf(stderr, "Warning: wasm2c altstack was modified unexpectedly\n");
free(alt_stack);
return;
}

free(alt_stack);
fprintf(stderr, "Warning: wasm2c altstack was modified unexpectedly\n");
}

static void os_cleanup_signal_handler(void) {
Expand All @@ -261,11 +259,8 @@ static void os_cleanup_signal_handler(void) {
#endif

void wasm_rt_init(void) {
wasm_rt_init_thread();
#if WASM_RT_INSTALL_SIGNAL_HANDLER
#if !WASM_RT_USE_STACK_DEPTH_COUNT
assert(!g_alt_stack);
g_alt_stack = os_allocate_and_install_altstack();
#endif
assert(!g_signal_handler_installed);
os_install_signal_handler();
g_signal_handler_installed = true;
Expand Down Expand Up @@ -294,27 +289,23 @@ void wasm_rt_free(void) {
#if WASM_RT_INSTALL_SIGNAL_HANDLER
os_cleanup_signal_handler();
g_signal_handler_installed = false;
#if !WASM_RT_USE_STACK_DEPTH_COUNT
assert(g_alt_stack);
os_disable_and_deallocate_altstack(g_alt_stack);
g_alt_stack = NULL;
#endif
#endif
wasm_rt_free_thread();
}

void* wasm_rt_init_thread(void) {
void wasm_rt_init_thread(void) {
#if WASM_RT_USE_STACK_DEPTH_COUNT || (!WASM_RT_INSTALL_SIGNAL_HANDLER)
return NULL;
return;
#else
return os_allocate_and_install_altstack();
os_allocate_and_install_altstack();
#endif
}

void wasm_rt_free_thread(void* alt_stack) {
void wasm_rt_free_thread(void) {
#if WASM_RT_USE_STACK_DEPTH_COUNT || (!WASM_RT_INSTALL_SIGNAL_HANDLER)
return;
#else
os_disable_and_deallocate_altstack(alt_stack);
os_disable_and_deallocate_altstack();
#endif
}

Expand Down
9 changes: 4 additions & 5 deletions wasm2c/wasm-rt.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,15 +335,14 @@ void wasm_rt_free(void);
* Initialize the multithreaded runtime for a given thread. Must be
* called by each thread (other than the one that called wasm_rt_init)
* before initializing a Wasm module or calling an exported
* function. Returns an opaque state pointer.
* function.
*/
void* wasm_rt_init_thread(void);
void wasm_rt_init_thread(void);

/*
* Free the individual thread's state, given the state returned by
* wasm_rt_init_thread().
* Free the individual thread's state.
*/
void wasm_rt_free_thread(void*);
void wasm_rt_free_thread(void);

/**
* A hardened jmp_buf that allows checking for initialization before use
Expand Down

0 comments on commit 9cfeb80

Please sign in to comment.