From: Jakub Jirutka Date: Wed, 8 Jun 2016 01:51:00 +0200 Subject: [PATCH] Try not to use address of local variable as stack address to copy. It triggers bounds check on musl libc that leads to Illegal instruction error. This patch is backported from https://github.com/JuliaLang/julia/pull/16813 --- a/src/gc.c +++ b/src/gc.c @@ -270,10 +270,7 @@ NOINLINE static uintptr_t gc_get_stack_ptr() { - void *dummy = NULL; - // The mask is to suppress the compiler warning about returning - // address of local variable - return (uintptr_t)&dummy & ~(uintptr_t)15; + return (uintptr_t)jl_get_frame_addr(); } #include "gc-debug.c" --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -222,6 +222,18 @@ DLLEXPORT jl_value_t *(jl_array_data_owner)(jl_array_t *a); +STATIC_INLINE void *jl_get_frame_addr(void) +{ +#ifdef __GNUC__ + return __builtin_frame_address(0); +#else + void *dummy = NULL; + // The mask is to suppress the compiler warning about returning + // address of local variable + return (void*)((uintptr_t)&dummy & ~(uintptr_t)15); +#endif +} + #ifdef __cplusplus } #endif --- a/src/task.c +++ b/src/task.c @@ -163,8 +163,8 @@ { if (t->state == done_sym || t->state == failed_sym) return; - volatile char *_x; - size_t nb = (char*)jl_stackbase - (char*)&_x; + char *frame_addr = (char*)jl_get_frame_addr(); + size_t nb = (char*)jl_stackbase - frame_addr; char *buf; if (t->stkbuf == NULL || t->bufsz < nb) { buf = (char*)allocb(nb); @@ -175,7 +175,7 @@ buf = (char*)t->stkbuf; } t->ssize = nb; - memcpy(buf, (char*)&_x, nb); + memcpy(buf, frame_addr, nb); // this task's stack could have been modified after // it was marked by an incremental collection // move the barrier back instead of walking it again here