static void tp_call_trace(VALUE tpval, rb_trace_arg_t *trace_arg) { rb_tp_t *tp = tpptr(tpval); if (tp->func) { (*tp->func)(tpval, tp->data); } else { rb_proc_call_with_block((VALUE)tp->proc, 1, &tpval, Qnil); } }
/* * call-seq: * trace.disable -> true or false * trace.disable { block } -> obj * * Deactivates the trace * * Return true if trace was enabled. * Return false if trace was disabled. * * trace.enabled? #=> true * trace.disable #=> false (previous status) * trace.enabled? #=> false * trace.disable #=> false * * If a block is given, the trace will only be disable within the scope of the * block. * * trace.enabled? * #=> true * * trace.disable do * trace.enabled? * # only disabled for this block * end * * trace.enabled? * #=> true * * Note: You cannot access event hooks within the block. * * trace.disable { p tp.lineno } * #=> RuntimeError: access from outside */ static VALUE tracepoint_disable_m(VALUE tpval) { rb_tp_t *tp = tpptr(tpval); int previous_tracing = tp->tracing; rb_tracepoint_disable(tpval); if (rb_block_given_p()) { return rb_ensure(rb_yield, Qnil, previous_tracing ? rb_tracepoint_enable : rb_tracepoint_disable, tpval); } else { return previous_tracing ? Qtrue : Qfalse; } }
VALUE rb_tracepoint_disable(VALUE tpval) { rb_tp_t *tp; tp = tpptr(tpval); if (tp->target_th) { rb_thread_remove_event_hook_with_data(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tpval); } else { rb_remove_event_hook_with_data((rb_event_hook_func_t)tp_call_trace, tpval); } tp->tracing = 0; return Qundef; }
static VALUE tracepoint_inspect(VALUE self) { rb_tp_t *tp = tpptr(self); rb_trace_arg_t *trace_arg = GET_THREAD()->trace_arg; if (trace_arg) { switch (trace_arg->event) { case RUBY_EVENT_LINE: case RUBY_EVENT_SPECIFIED_LINE: { VALUE sym = rb_tracearg_method_id(trace_arg); if (NIL_P(sym)) goto default_inspect; return rb_sprintf("#<TracePoint:%"PRIsVALUE"@%"PRIsVALUE":%d in `%"PRIsVALUE"'>", rb_tracearg_event(trace_arg), rb_tracearg_path(trace_arg), FIX2INT(rb_tracearg_lineno(trace_arg)), sym); } case RUBY_EVENT_CALL: case RUBY_EVENT_C_CALL: case RUBY_EVENT_RETURN: case RUBY_EVENT_C_RETURN: return rb_sprintf("#<TracePoint:%"PRIsVALUE" `%"PRIsVALUE"'@%"PRIsVALUE":%d>", rb_tracearg_event(trace_arg), rb_tracearg_method_id(trace_arg), rb_tracearg_path(trace_arg), FIX2INT(rb_tracearg_lineno(trace_arg))); case RUBY_EVENT_THREAD_BEGIN: case RUBY_EVENT_THREAD_END: return rb_sprintf("#<TracePoint:%"PRIsVALUE" %"PRIsVALUE">", rb_tracearg_event(trace_arg), rb_tracearg_self(trace_arg)); default: default_inspect: return rb_sprintf("#<TracePoint:%"PRIsVALUE"@%"PRIsVALUE":%d>", rb_tracearg_event(trace_arg), rb_tracearg_path(trace_arg), FIX2INT(rb_tracearg_lineno(trace_arg))); } } else { return rb_sprintf("#<TracePoint:%s>", tp->tracing ? "enabled" : "disabled"); } }
VALUE rb_tracepoint_enable(VALUE tpval) { rb_tp_t *tp; tp = tpptr(tpval); if (tp->target_th) { rb_thread_add_event_hook2(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tp->events, tpval, RUBY_EVENT_HOOK_FLAG_SAFE | RUBY_EVENT_HOOK_FLAG_RAW_ARG); } else { rb_add_event_hook2((rb_event_hook_func_t)tp_call_trace, tp->events, tpval, RUBY_EVENT_HOOK_FLAG_SAFE | RUBY_EVENT_HOOK_FLAG_RAW_ARG); } tp->tracing = 1; return Qundef; }
/* * call-seq: * trace.enabled? -> true or false * * The current status of the trace */ VALUE rb_tracepoint_enabled_p(VALUE tpval) { rb_tp_t *tp = tpptr(tpval); return tp->tracing ? Qtrue : Qfalse; }