Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ static void NOINLINE save_stack(jl_ptls_t ptls, jl_task_t *lastt, jl_task_t **pt
if (lastt->ctx.bufsz < nb) {
asan_free_copy_stack(lastt->ctx.stkbuf, lastt->ctx.bufsz);
buf = (void*)jl_gc_alloc_buf(ptls, nb);
jl_gc_wb(lastt, buf);
lastt->ctx.stkbuf = buf;
lastt->ctx.bufsz = nb;
}
Expand Down Expand Up @@ -1593,7 +1594,7 @@ jl_task_t *jl_init_root_task(jl_ptls_t ptls, void *stack_lo, void *stack_hi)
if (always_copy_stacks) {
// when this is set, we will attempt to corrupt the process stack to switch tasks,
// although this is unreliable, and thus not recommended
ptls->stackbase = jl_get_frame_addr();
ptls->stackbase = (void*)((uintptr_t)jl_get_frame_addr() & ~(uintptr_t)15);
ptls->stacksize = (char*)ptls->stackbase - (char*)stack_lo;
}
else {
Expand Down
18 changes: 18 additions & 0 deletions test/threads.jl
Original file line number Diff line number Diff line change
Expand Up @@ -587,3 +587,21 @@ let once = OncePerTask{Int}(() -> error("expected"))
@test_throws ErrorException("expected") once()
@test_throws ErrorException("expected") once()
end

# Exercise `save_stack`/`restore_stack` under GC pressure: a missing write-barrier
# when storing the freshly-allocated copy-stack buffer into `lastt->ctx.stkbuf`
# let the GC collect the buffer while the (old) task still referenced it.
let code = """
function f(x)
x in (0, 1) && return x
a = Threads.@spawn f(x - 2)
b = Threads.@spawn f(x - 1)
return fetch(a) + fetch(b)
end
print(@sync f(25))
"""
cmd = addenv(`$(Base.julia_cmd()) --depwarn=error --startup-file=no -t4 -e $code`,
"JULIA_COPY_STACKS" => "1")
# JULIA_COPY_STACKS is broken on Windows (#35147)
@test read(cmd, String) == "75025" skip=Sys.iswindows()
end