static void call_event(VALUE trace_point, void *data) { VALUE breakpoint, klass, msym, mid, binding, self, file, line; EVENT_SETUP dc->calced_stack_size++; if (CTX_FL_TEST(dc, CTX_FL_STOP_ON_RET)) dc->steps_out = dc->steps_out <= 0 ? -1 : dc->steps_out + 1; EVENT_COMMON breakpoint = Qnil; klass = rb_tracearg_defined_class(trace_arg); msym = rb_tracearg_method_id(trace_arg); mid = NIL_P(msym) ? Qnil : SYM2ID(msym); binding = rb_tracearg_binding(trace_arg); self = rb_tracearg_self(trace_arg); file = rb_tracearg_path(trace_arg); line = rb_tracearg_lineno(trace_arg); breakpoint = find_breakpoint_by_method(breakpoints, klass, mid, binding, self); if (breakpoint != Qnil) { call_at_breakpoint(context, dc, breakpoint); call_at_line(context, dc, file, line); } cleanup(dc); }
static void eval_trace_callback(void *data, rb_trace_arg_t *trace_arg) { rb_event_flag_t event; VALUE evaluator; VALUE klass; VALUE obj; VALUE method_id; ID trace_func_cb_id; ID trace_c_func_cb_id; CONST_ID(trace_func_cb_id, "trace_func_callback"); CONST_ID(trace_c_func_cb_id, "trace_c_func_callback"); event = rb_tracearg_event_flag(trace_arg); evaluator = (VALUE)data; obj = rb_tracearg_self(trace_arg); method_id = rb_tracearg_method_id(trace_arg); klass = rb_tracearg_defined_class(trace_arg); if (event & RUBY_EVENT_CALL) { rb_funcall(evaluator, trace_func_cb_id, 3, obj, klass, method_id); } if (event & RUBY_EVENT_C_CALL) { rb_funcall(evaluator, trace_c_func_cb_id, 3, obj, klass, method_id); } return; }
static void call_event(VALUE trace_point, void *data) { VALUE breakpoint, klass, mid, binding, self, file, line; EVENT_SETUP dc->calced_stack_size++; EVENT_COMMON breakpoint = Qnil; klass = rb_tracearg_defined_class(trace_arg); mid = SYM2ID(rb_tracearg_method_id(trace_arg)); binding = rb_tracearg_binding(trace_arg); self = rb_tracearg_self(trace_arg); file = rb_tracearg_path(trace_arg); line = rb_tracearg_lineno(trace_arg); breakpoint = find_breakpoint_by_method(breakpoints, klass, mid, binding, self); if (breakpoint != Qnil) { call_at_breakpoint(context, dc, breakpoint); call_at_line(context, dc, file, line); } cleanup(dc); }
static void trace_print(rb_trace_arg_t * trace_arg, debug_context_t * dc, const char *file_filter, const char *debug_msg) { char *fullpath = NULL; const char *basename; int filtered = 0; const char *event = rb_id2name(SYM2ID(rb_tracearg_event(trace_arg))); VALUE rb_path = rb_tracearg_path(trace_arg); const char *path = NIL_P(rb_path) ? "" : RSTRING_PTR(rb_path); int line = NUM2INT(rb_tracearg_lineno(trace_arg)); VALUE rb_mid = rb_tracearg_method_id(trace_arg); const char *mid = NIL_P(rb_mid) ? "(top level)" : rb_id2name(SYM2ID(rb_mid)); VALUE rb_cl = rb_tracearg_defined_class(trace_arg); VALUE rb_cl_name = NIL_P(rb_cl) ? rb_cl : rb_mod_name(rb_cl); const char *defined_class = NIL_P(rb_cl_name) ? "" : RSTRING_PTR(rb_cl_name); if (!trace_arg) return; if (file_filter) { #ifndef _WIN32 fullpath = realpath(path, NULL); #endif basename = fullpath ? strrchr(fullpath, '/') : path; if (!basename || strncmp(basename + 1, file_filter, strlen(file_filter))) filtered = 1; #ifndef _WIN32 free(fullpath); #endif } if (!filtered) { if (debug_msg) rb_funcall(mByebug, idPuts, 1, rb_sprintf("[#%d] %s\n", dc->thnum, debug_msg)); else rb_funcall(mByebug, idPuts, 1, rb_sprintf("%*s [#%d] %s@%s:%d %s#%s\n", dc->calced_stack_size, "", dc->thnum, event, path, line, defined_class, mid)); } }
static void call_event(VALUE trace_point, void *data) { VALUE brkpnt, klass, msym, mid, binding, self, file, line; EVENT_SETUP; if (dc->calced_stack_size <= dc->dest_frame) CTX_FL_UNSET(dc, CTX_FL_IGNORE_STEPS); dc->calced_stack_size++; dc->steps_out = dc->steps_out <= 0 ? -1 : dc->steps_out + 1; /* nil method_id means we are at top level so there can't be a method * breakpoint here. Just leave then. */ msym = rb_tracearg_method_id(trace_arg); if (NIL_P(msym)) { EVENT_TEARDOWN; return; } mid = SYM2ID(msym); klass = rb_tracearg_defined_class(trace_arg); binding = rb_tracearg_binding(trace_arg); self = rb_tracearg_self(trace_arg); file = rb_tracearg_path(trace_arg); line = rb_tracearg_lineno(trace_arg); brkpnt = Qnil; if (!NIL_P(breakpoints)) brkpnt = find_breakpoint_by_method(breakpoints, klass, mid, binding, self); if (!NIL_P(brkpnt)) { call_at_breakpoint(context, dc, brkpnt); call_at_line(context, dc, file, line); } EVENT_TEARDOWN; }
/* * Return class or module of the method being called. * * class C; def foo; end; end * trace = TracePoint.new(:call) do |tp| * p tp.defined_class #=> C * end.enable do * C.new.foo * end * * If method is defined by a module, then that module is returned. * * module M; def foo; end; end * class C; include M; end; * trace = TracePoint.new(:call) do |tp| * p tp.defined_class #=> M * end.enable do * C.new.foo * end * * <b>Note:</b> #defined_class returns singleton class. * * 6th block parameter of Kernel#set_trace_func passes original class * of attached by singleton class. * * <b>This is a difference between Kernel#set_trace_func and TracePoint.</b> * * class C; def self.foo; end; end * trace = TracePoint.new(:call) do |tp| * p tp.defined_class #=> #<Class:C> * end.enable do * C.foo * end */ static VALUE tracepoint_attr_defined_class(VALUE tpval) { return rb_tracearg_defined_class(get_trace_arg()); }