mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
notify ASAN about M:N threading stack switches
In a similar way to how we do it with fibers in cont.c, we need to call __sanitize_start_switch_fiber and __sanitize_finish_switch_fiber around the call to coroutine_transfer to let ASAN save & restore the fake stack pointer. When a M:N thread is exiting, we pass `to_dead` to the new coroutine_transfer0 function, so that we can pass NULL for saving the stack pointer. This signals to ASAN that the fake stack can be freed (otherwise it would be leaked) [Bug #20220]
This commit is contained in:
parent
19f615521d
commit
719db18b50
2 changed files with 36 additions and 7 deletions
|
@ -413,6 +413,11 @@ native_thread_check_and_create_shared(rb_vm_t *vm)
|
|||
static COROUTINE
|
||||
co_start(struct coroutine_context *from, struct coroutine_context *self)
|
||||
{
|
||||
#ifdef RUBY_ASAN_ENABLED
|
||||
__sanitizer_finish_switch_fiber(self->fake_stack,
|
||||
(const void**)&from->stack_base, &from->stack_size);
|
||||
#endif
|
||||
|
||||
rb_thread_t *th = (rb_thread_t *)self->argument;
|
||||
struct rb_thread_sched *sched = TH_SCHED(th);
|
||||
VM_ASSERT(th->nt != NULL);
|
||||
|
@ -447,13 +452,13 @@ co_start(struct coroutine_context *from, struct coroutine_context *self)
|
|||
if (!has_ready_ractor && next_th && !next_th->nt) {
|
||||
// switch to the next thread
|
||||
thread_sched_set_lock_owner(sched, NULL);
|
||||
thread_sched_switch0(th->sched.context, next_th, nt);
|
||||
thread_sched_switch0(th->sched.context, next_th, nt, true);
|
||||
th->sched.finished = true;
|
||||
}
|
||||
else {
|
||||
// switch to the next Ractor
|
||||
th->sched.finished = true;
|
||||
coroutine_transfer(self, nt->nt_context);
|
||||
coroutine_transfer0(self, nt->nt_context, true);
|
||||
}
|
||||
rb_bug("unreachable");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue