Example #1
0
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;
        }
    }
}
Example #2
0
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;
    }
}
Example #3
0
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");
}
Example #4
0
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));
    }
}