Replies: 2 comments 1 reply
-
Apparently the initialization fails when the result of package main
import (
"fmt"
"sync"
"unsafe"
)
/*
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#define APP_THREAD_STACK_SIZE_MAX (8 * 1024 * 1024)
#define STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT 3
char *check_aligned(uint8_t *addr) {
if ((intptr_t)addr % 16384 == 0) return "aligned to 16KiB";
if ((intptr_t)addr % 4096 == 0) return "aligned to 4KiB";
return "unaligned to 4KiB or 16KiB";
}
void check_stack_boundary(int32_t i) {
pthread_t self = pthread_self();
uint8_t *addr = (uint8_t *)pthread_get_stackaddr_np(self);
size_t page_size = getpagesize();
size_t stack_size = pthread_get_stacksize_np(self);
size_t max_stack_size = (size_t)(APP_THREAD_STACK_SIZE_MAX + page_size - 1) & ~(page_size - 1);
fprintf(stdout, "%d.1|stack addr np %s (%p)\n", i, check_aligned(addr), addr);
fprintf(stdout, "%d.2|page size: %zu\n", i, page_size);
fprintf(stdout, "%d.3|stack size: %zu\n", i, stack_size);
fprintf(stdout, "%d.4|max stack size: %zu\n", i, max_stack_size);
if (addr <= (uint8_t *)&stack_size) addr = addr + stack_size;
if (stack_size > max_stack_size) stack_size = max_stack_size;
addr -= stack_size;
addr += page_size;
fprintf(stdout, "%d.6|stack boundary %s (%p)\n", i, check_aligned(addr), addr);
bool ok = mprotect(addr, page_size * STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT, PROT_NONE) == 0;
if (ok) fprintf(stdout, "%d.8|mprotect succeeded!\n", i);
else fprintf(stdout, "%d.8|mprotect failed: %s\n", i, strerror(errno));
}
*/
import "C"
func main() {
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
i := i
wg.Add(1)
go func() {
C.my_os_thread_get_stack_boundary((C.int32_t)(i))
wg.Done()
}()
}
wg.Wait()
}
|
Beta Was this translation helpful? Give feedback.
-
@benozol wasm_runtime_init or wasm_runtime_full_init should have initialize the thread env of the current thread: wasm_runtime_init -> wasm_runtime_env_init -> runtime_signal_init -> os_thread_signal_init, not sure why it fails. And do you mean the page size in MacOS is 16384? It is a little strange, normally it is 4096? |
Beta Was this translation helpful? Give feedback.
-
Using the Go bindings in a goroutine can trigger a failure in
InitThreadEnv()
, which is preceded by the messageFailed to init stack guard pages
. In the example below, this happens roughly at every second run (MacOS).The failure is not prevented by using a mutex on the goroutine. I'm unable to reproduce the failure in C using
pthread.h
.Is my use of
InitThreadEnv()
invalid? Is some other locking mechanism required in the context of goroutines?Beta Was this translation helpful? Give feedback.
All reactions