From e5064071afc21d23de2791bb1b3ca01e5d2786cc Mon Sep 17 00:00:00 2001 From: David Roman Date: Tue, 17 Mar 2026 20:57:08 -0400 Subject: [PATCH] fix: after more tests with golang --- quickjs.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/quickjs.c b/quickjs.c index 4f16f40..760d1c5 100644 --- a/quickjs.c +++ b/quickjs.c @@ -1641,11 +1641,16 @@ static inline BOOL js_check_stack_overflow(JSRuntime *rt, size_t alloca_size) /* Detect when the runtime is being called from a different thread or fiber than the one that set stack_top. In M:N threading models (green threads, fibers, coroutines), each execution context has its - own stack at an unrelated address. If sp is outside the expected - range, re-anchor stack_top to the current stack before checking. - A genuine overflow has sp just below stack_limit; a context switch - has sp in a completely different address range. */ - if (unlikely(sp > rt->stack_top || sp + rt->stack_size < rt->stack_limit)) { + own stack at an unrelated address. Re-anchor stack_top whenever sp + is outside [stack_limit, stack_top]. + + The previous check (sp + stack_size < stack_limit) missed the case + where the new thread's stack is between 1x and 2x stack_size below + the original stack_top. Checking sp < stack_limit directly closes + this gap. With typical embedder stack_size values (256MB+) that far + exceed real C thread stacks (1-8MB), re-anchoring never masks a + genuine overflow, the OS catches those via SIGSEGV. */ + if (unlikely(sp > rt->stack_top || sp < rt->stack_limit)) { JS_UpdateStackTop(rt); sp = js_get_stack_pointer() - alloca_size; }