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 */
|
||