Skip to content

Commit 7a934a8

Browse files
Check for VM_ENV_DATA_INDEX_FLAGS in mid-escape
vm_make_env_each iterates over frames on the stack, escaping each one. This can leave the stack in an inconsistent state. If a sampling profiler calls rb_profile_frames from a signal handler, it can observe the stack in this inconsistent state, so we need to check for it. Co-authored-by: Nery Campusano <nery.campusano@shopify.com>
1 parent aee9122 commit 7a934a8

1 file changed

Lines changed: 6 additions & 1 deletion

File tree

vm_insnhelper.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,12 @@ rb_vm_frame_method_entry(const rb_control_frame_t *cfp)
771771
const VALUE *ep = cfp->ep;
772772
rb_callable_method_entry_t *me;
773773

774-
while (!VM_ENV_LOCAL_P(ep)) {
774+
for (;;) {
775+
if (UNLIKELY(!FIXNUM_P(ep[VM_ENV_DATA_INDEX_FLAGS]))) {
776+
// vm_make_env_each mid-escape: flags slot holds the env object.
777+
ep = ((const rb_env_t *)ep[VM_ENV_DATA_INDEX_FLAGS])->ep;
778+
}
779+
if (VM_ENV_LOCAL_P(ep)) break;
775780
if ((me = check_method_entry(ep[VM_ENV_DATA_INDEX_ME_CREF], FALSE)) != NULL) return me;
776781
ep = VM_ENV_PREV_EP(ep);
777782
}

0 commit comments

Comments
 (0)