Check ASAN fake stacks when marking non-current threads
Currently, we check the values on the machine stack & register state to see if they're actually a pointer to an ASAN fake stack, and mark the values on the fake stack too if required. However, we are only doing that for the _current_ thread (the one actually running the GC), not for any other thread in the program. Make rb_gc_mark_machine_context (which is called for marking non-current threads) perform the same ASAN fake stack handling that mark_current_machine_context performs. [Bug #20310]
This commit is contained in:
parent
48d3bdddba
commit
2535a09e85
20
gc.c
20
gc.c
@ -949,7 +949,7 @@ typedef struct rb_objspace {
|
|||||||
rb_postponed_job_handle_t finalize_deferred_pjob;
|
rb_postponed_job_handle_t finalize_deferred_pjob;
|
||||||
|
|
||||||
#ifdef RUBY_ASAN_ENABLED
|
#ifdef RUBY_ASAN_ENABLED
|
||||||
rb_execution_context_t *marking_machine_context_ec;
|
const rb_execution_context_t *marking_machine_context_ec;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} rb_objspace_t;
|
} rb_objspace_t;
|
||||||
@ -6406,7 +6406,7 @@ gc_mark_machine_stack_location_maybe(rb_objspace_t *objspace, VALUE obj)
|
|||||||
gc_mark_maybe(objspace, obj);
|
gc_mark_maybe(objspace, obj);
|
||||||
|
|
||||||
#ifdef RUBY_ASAN_ENABLED
|
#ifdef RUBY_ASAN_ENABLED
|
||||||
rb_execution_context_t *ec = objspace->marking_machine_context_ec;
|
const rb_execution_context_t *ec = objspace->marking_machine_context_ec;
|
||||||
void *fake_frame_start;
|
void *fake_frame_start;
|
||||||
void *fake_frame_end;
|
void *fake_frame_end;
|
||||||
bool is_fake_frame = asan_get_fake_stack_extents(
|
bool is_fake_frame = asan_get_fake_stack_extents(
|
||||||
@ -6495,13 +6495,25 @@ mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_gc_mark_machine_stack(const rb_execution_context_t *ec)
|
rb_gc_mark_machine_context(const rb_execution_context_t *ec)
|
||||||
{
|
{
|
||||||
|
rb_objspace_t *objspace = &rb_objspace;
|
||||||
|
#ifdef RUBY_ASAN_ENABLED
|
||||||
|
objspace->marking_machine_context_ec = ec;
|
||||||
|
#endif
|
||||||
|
|
||||||
VALUE *stack_start, *stack_end;
|
VALUE *stack_start, *stack_end;
|
||||||
|
|
||||||
GET_STACK_BOUNDS(stack_start, stack_end, 0);
|
GET_STACK_BOUNDS(stack_start, stack_end, 0);
|
||||||
RUBY_DEBUG_LOG("ec->th:%u stack_start:%p stack_end:%p", rb_ec_thread_ptr(ec)->serial, stack_start, stack_end);
|
RUBY_DEBUG_LOG("ec->th:%u stack_start:%p stack_end:%p", rb_ec_thread_ptr(ec)->serial, stack_start, stack_end);
|
||||||
|
|
||||||
rb_gc_mark_locations(stack_start, stack_end);
|
each_stack_location(objspace, ec, stack_start, stack_end, gc_mark_machine_stack_location_maybe);
|
||||||
|
int num_regs = sizeof(ec->machine.regs)/(sizeof(VALUE));
|
||||||
|
each_location(objspace, (VALUE*)&ec->machine.regs, num_regs, gc_mark_machine_stack_location_maybe);
|
||||||
|
|
||||||
|
#ifdef RUBY_ASAN_ENABLED
|
||||||
|
objspace->marking_machine_context_ec = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
5
vm.c
5
vm.c
@ -3399,10 +3399,7 @@ rb_execution_context_mark(const rb_execution_context_t *ec)
|
|||||||
if (ec->machine.stack_start && ec->machine.stack_end &&
|
if (ec->machine.stack_start && ec->machine.stack_end &&
|
||||||
ec != GET_EC() /* marked for current ec at the first stage of marking */
|
ec != GET_EC() /* marked for current ec at the first stage of marking */
|
||||||
) {
|
) {
|
||||||
rb_gc_mark_machine_stack(ec);
|
rb_gc_mark_machine_context(ec);
|
||||||
rb_gc_mark_locations((VALUE *)&ec->machine.regs,
|
|
||||||
(VALUE *)(&ec->machine.regs) +
|
|
||||||
sizeof(ec->machine.regs) / (sizeof(VALUE)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_gc_mark(ec->errinfo);
|
rb_gc_mark(ec->errinfo);
|
||||||
|
@ -1874,7 +1874,7 @@ void rb_vm_register_special_exception_str(enum ruby_special_exceptions sp, VALUE
|
|||||||
#define rb_vm_register_special_exception(sp, e, m) \
|
#define rb_vm_register_special_exception(sp, e, m) \
|
||||||
rb_vm_register_special_exception_str(sp, e, rb_usascii_str_new_static((m), (long)rb_strlen_lit(m)))
|
rb_vm_register_special_exception_str(sp, e, rb_usascii_str_new_static((m), (long)rb_strlen_lit(m)))
|
||||||
|
|
||||||
void rb_gc_mark_machine_stack(const rb_execution_context_t *ec);
|
void rb_gc_mark_machine_context(const rb_execution_context_t *ec);
|
||||||
|
|
||||||
void rb_vm_rewrite_cref(rb_cref_t *node, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr);
|
void rb_vm_rewrite_cref(rb_cref_t *node, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user