Bug #13412 » get_tagged_next_cfp.patch
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 */
|
||