static void rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p) { rb_thread_t *th = trace_arg->th; if (trace_arg->event & RUBY_INTERNAL_EVENT_MASK) { if (th->trace_arg && (th->trace_arg->event & RUBY_INTERNAL_EVENT_MASK)) { /* skip hooks because this thread doing INTERNAL_EVENT */ } else { rb_trace_arg_t *prev_trace_arg = th->trace_arg; th->trace_arg = trace_arg; exec_hooks_unprotected(th, &th->event_hooks, trace_arg); exec_hooks_unprotected(th, &th->vm->event_hooks, trace_arg); th->trace_arg = prev_trace_arg; } } else { if (th->trace_arg == 0 && /* check reentrant */ trace_arg->self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) { const VALUE errinfo = th->errinfo; const int outer_state = th->state; int state = 0; th->state = 0; th->errinfo = Qnil; th->vm->trace_running++; th->trace_arg = trace_arg; { /* thread local traces */ state = exec_hooks_protected(th, &th->event_hooks, trace_arg); if (state) goto terminate; /* vm global traces */ state = exec_hooks_protected(th, &th->vm->event_hooks, trace_arg); if (state) goto terminate; th->errinfo = errinfo; } terminate: th->trace_arg = 0; th->vm->trace_running--; if (state) { if (pop_p) { if (VM_FRAME_TYPE_FINISH_P(th->cfp)) { th->tag = th->tag->prev; } th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); } TH_JUMP_TAG(th, state); } th->state = outer_state; } } }
static void rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p) { rb_thread_t *th = trace_arg->th; if (th->trace_arg == 0 && trace_arg->self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) { const int vm_tracing = th->vm->trace_running; const VALUE errinfo = th->errinfo; const int outer_state = th->state; int state = 0; th->state = 0; th->vm->trace_running++; th->trace_arg = trace_arg; { rb_hook_list_t *list; /* thread local traces */ list = &th->event_hooks; if (list->events & trace_arg->event) { state = exec_hooks(th, list, trace_arg, TRUE); if (state) goto terminate; } /* vm global traces */ list = &th->vm->event_hooks; if (list->events & trace_arg->event) { state = exec_hooks(th, list, trace_arg, !vm_tracing); if (state) goto terminate; } th->errinfo = errinfo; } terminate: th->trace_arg = 0; th->vm->trace_running--; if (state) { if (pop_p) { if (VM_FRAME_TYPE_FINISH_P(th->cfp)) { th->tag = th->tag->prev; } th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); } TH_JUMP_TAG(th, state); } th->state = outer_state; } }
static void control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp) { ptrdiff_t pc = -1; ptrdiff_t ep = cfp->ep - th->stack; char ep_in_heap = ' '; char posbuf[MAX_POSBUF+1]; int line = 0; const char *magic, *iseq_name = "-", *selfstr = "-", *biseq_name = "-"; VALUE tmp; if (cfp->block_iseq != 0 && BUILTIN_TYPE(cfp->block_iseq) != T_NODE) { biseq_name = ""; /* RSTRING(cfp->block_iseq->location.label)->ptr; */ } if (ep < 0 || (size_t)ep > th->stack_size) { ep = (ptrdiff_t)cfp->ep; ep_in_heap = 'p'; } switch (VM_FRAME_TYPE(cfp)) { case VM_FRAME_MAGIC_TOP: magic = "TOP"; break; case VM_FRAME_MAGIC_METHOD: magic = "METHOD"; break; case VM_FRAME_MAGIC_CLASS: magic = "CLASS"; break; case VM_FRAME_MAGIC_BLOCK: magic = "BLOCK"; break; case VM_FRAME_MAGIC_CFUNC: magic = "CFUNC"; break; case VM_FRAME_MAGIC_PROC: magic = "PROC"; break; case VM_FRAME_MAGIC_LAMBDA: magic = "LAMBDA"; break; case VM_FRAME_MAGIC_IFUNC: magic = "IFUNC"; break; case VM_FRAME_MAGIC_EVAL: magic = "EVAL"; break; case 0: magic = "------"; break; default: magic = "(none)"; break; } if (0) { tmp = rb_inspect(cfp->self); selfstr = StringValueCStr(tmp); } else { selfstr = ""; } if (cfp->iseq != 0) { if (RUBY_VM_IFUNC_P(cfp->iseq)) { iseq_name = "<ifunc>"; } else { pc = cfp->pc - cfp->iseq->iseq_encoded; iseq_name = RSTRING_PTR(cfp->iseq->location.label); line = rb_vm_get_sourceline(cfp); if (line) { snprintf(posbuf, MAX_POSBUF, "%s:%d", RSTRING_PTR(cfp->iseq->location.path), line); } } } else if (cfp->me) { iseq_name = rb_id2name(cfp->me->def->original_id); snprintf(posbuf, MAX_POSBUF, ":%s", iseq_name); line = -1; } fprintf(stderr, "c:%04"PRIdPTRDIFF" ", ((rb_control_frame_t *)(th->stack + th->stack_size) - cfp)); if (pc == -1) { fprintf(stderr, "p:---- "); } else { fprintf(stderr, "p:%04"PRIdPTRDIFF" ", pc); } fprintf(stderr, "s:%04"PRIdPTRDIFF" ", cfp->sp - th->stack); fprintf(stderr, ep_in_heap == ' ' ? "e:%06"PRIdPTRDIFF" " : "e:%06"PRIxPTRDIFF" ", ep % 10000); fprintf(stderr, "%-6s", magic); if (line) { fprintf(stderr, " %s", posbuf); } if (VM_FRAME_TYPE_FINISH_P(cfp)) { fprintf(stderr, " [FINISH]"); } if (0) { fprintf(stderr, " \t"); fprintf(stderr, "iseq: %-24s ", iseq_name); fprintf(stderr, "self: %-24s ", selfstr); fprintf(stderr, "%-1s ", biseq_name); } fprintf(stderr, "\n"); }
static void vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp) { int i; VALUE rstr; VALUE *sp = cfp->sp; VALUE *ep = cfp->ep; int argc = 0, local_size = 0; const char *name; rb_iseq_t *iseq = cfp->iseq; if (iseq == 0) { if (RUBYVM_CFUNC_FRAME_P(cfp)) { name = rb_id2name(cfp->me->called_id); } else { name = "?"; } } else if (RUBY_VM_IFUNC_P(iseq)) { name = "<ifunc>"; } else { argc = iseq->argc; local_size = iseq->local_size; name = RSTRING_PTR(iseq->location.label); } /* stack trace header */ if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_METHOD || VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_TOP || VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_BLOCK || VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CLASS || VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_PROC || VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA || VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC || VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_IFUNC || VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_EVAL) { VALUE *ptr = ep - local_size; control_frame_dump(th, cfp); for (i = 0; i < argc; i++) { rstr = rb_inspect(*ptr); fprintf(stderr, " arg %2d: %8s (%p)\n", i, StringValueCStr(rstr), (void *)ptr++); } for (; i < local_size - 1; i++) { rstr = rb_inspect(*ptr); fprintf(stderr, " local %2d: %8s (%p)\n", i, StringValueCStr(rstr), (void *)ptr++); } ptr = vm_base_ptr(cfp); for (; ptr < sp; ptr++, i++) { if (*ptr == Qundef) { rstr = rb_str_new2("undef"); } else { rstr = rb_inspect(*ptr); } fprintf(stderr, " stack %2d: %8s (%"PRIdPTRDIFF")\n", i, StringValueCStr(rstr), (ptr - th->stack)); } } else if (VM_FRAME_TYPE_FINISH_P(cfp)) { if ((th)->stack + (th)->stack_size > (VALUE *)(cfp + 1)) { vm_stack_dump_each(th, cfp + 1); } else { /* SDR(); */ } } else { rb_bug("unsupport frame type: %08lx", VM_FRAME_TYPE(cfp)); } }