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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
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