Project

General

Profile

Bug #13412 » get_tagged_next_cfp.patch

wanabe (_ wanabe), 04/17/2017 12:02 AM

View differences:

eval_intern.h
{
int state = th->state;
th->state = 0;
th->cfp->status |= CF_STATUS_TAGGED;
return state;
}
signal.c
if (sp_page == fault_page || sp_page == fault_page + 1 ||
sp_page <= fault_page && fault_page <= bp_page) {
rb_thread_t *th = ruby_current_thread;
th->cfp = rb_vm_get_tagged_next_cfp(th, th->cfp);
if ((uintptr_t)th->tag->buf / pagesize <= fault_page + 1) {
/* drop the last tag if it is close to the fault,
* otherwise it can cause stack overflow again at the same
* place. */
th->tag = th->tag->prev;
th->cfp = rb_vm_get_tagged_next_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp));
}
raise_stack_overflow(sig, th);
}
vm.c
return 0;
}
rb_control_frame_t *
rb_vm_get_tagged_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp)
{
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
if (cfp->status & CF_STATUS_TAGGED) {
return (rb_control_frame_t *)cfp;
}
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
return 0;
}
void
rb_vm_pop_cfunc_frame(void)
{
vm_core.h
enum rb_block_type type;
};
typedef enum {
CF_STATUS_INITIALIZED = 0x00,
CF_STATUS_TAGGED = 0x01,
} rb_control_ftame_status_t;
typedef struct rb_control_frame_struct {
const VALUE *pc; /* cfp[0] */
VALUE *sp; /* cfp[1] */
......
VALUE self; /* cfp[3] / block[0] */
const VALUE *ep; /* cfp[4] / block[1] */
const void *block_code; /* cfp[5] / block[2] */ /* iseq or ifunc */
rb_control_ftame_status_t status;
#if VM_DEBUG_BP_CHECK
VALUE *bp_check; /* cfp[6] */
VALUE *bp_check; /* cfp[7] */
#endif
} rb_control_frame_t;
......
typedef int rb_backtrace_iter_func(void *, VALUE, int, VALUE);
rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp);
rb_control_frame_t *rb_vm_get_binding_creatable_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp);
rb_control_frame_t *rb_vm_get_tagged_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp);
int rb_vm_get_sourceline(const rb_control_frame_t *);
VALUE rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method);
void rb_vm_stack_to_heap(rb_thread_t *th);
vm_insnhelper.c
cfp->iseq = (rb_iseq_t *)iseq;
cfp->self = self;
cfp->block_code = NULL;
cfp->status = CF_STATUS_INITIALIZED;
/* setup vm value stack */
(12-12/13)