/* * call-seq: * Byebug.debug_load(file, stop = false) -> nil * * Same as Kernel#load but resets current context's frames. * +stop+ parameter forces byebug to stop at the first line of code in +file+ */ static VALUE Debug_load(int argc, VALUE * argv, VALUE self) { VALUE file, stop, context; debug_context_t *dc; VALUE status = Qnil; int state = 0; UNUSED(self); if (rb_scan_args(argc, argv, "11", &file, &stop) == 1) stop = Qfalse; Start(self); context = Current_context(self); Data_Get_Struct(context, debug_context_t, dc); dc->calced_stack_size = 1; if (RTEST(stop)) dc->steps = 1; rb_load_protect(file, 0, &state); if (0 != state) { status = rb_errinfo(); reset_stepping_stop_points(dc); } return status; }
static void call_at_line_check(VALUE context_obj, debug_context_t *dc, VALUE breakpoint, VALUE file, VALUE line) { dc->stop_reason = CTX_STOP_STEP; if (breakpoint != Qnil) call_at_breakpoint(context_obj, dc, breakpoint); reset_stepping_stop_points(dc); call_at_line(context_obj, dc, file, line); }
extern VALUE context_dup(debug_context_t * context) { debug_context_t *new_context = ALLOC(debug_context_t); memcpy(new_context, context, sizeof(debug_context_t)); reset_stepping_stop_points(new_context); new_context->backtrace = context->backtrace; CTX_FL_SET(new_context, CTX_FL_DEAD); return Data_Wrap_Struct(cContext, context_mark, 0, new_context); }
static void call_at_line_check(VALUE ctx, debug_context_t * dc, VALUE breakpoint) { dc->stop_reason = CTX_STOP_STEP; if (!NIL_P(breakpoint)) call_at_breakpoint(ctx, dc, breakpoint); reset_stepping_stop_points(dc); call_at_line(ctx, dc); }
static void return_event(VALUE trace_point, void *data) { VALUE brkpnt, file, line, binding; EVENT_SETUP; RETURN_EVENT_SETUP; if ((dc->steps_out == 0) && (CTX_FL_TEST(dc, CTX_FL_STOP_ON_RET))) { reset_stepping_stop_points(dc); call_at_return(context, dc, rb_tracearg_return_value(trace_arg)); } else if (!NIL_P(breakpoints)) { file = rb_tracearg_path(trace_arg); /* * @todo Sometimes the TracePoint API gives some return events without * file:line information, so we need to guard for nil until we know what's * going on. This happens, for example, with active_support core extensions: * * [#7] call@.../core_ext/numeric/conversions.rb:124 Fixnum#to_s * [#7] b_call@.../core_ext/numeric/conversions.rb:124 BigDecimal#to_s * [#7] line@.../core_ext/numeric/conversions.rb:125 BigDecimal#to_s * [#7] c_call@.../core_ext/numeric/conversions.rb:125 Kernel#is_a? * [#7] c_return@.../core_ext/numeric/conversions.rb:125 Kernel#is_a? * [#7] line@.../core_ext/numeric/conversions.rb:131 BigDecimal#to_s * [#7] c_call@.../core_ext/numeric/conversions.rb:131 Fixnum#to_default_s * [#7] c_return@.../core_ext/numeric/conversions.rb:131 Fixnum#to_default_s * [#7] b_return@/hort/core_ext/numeric/conversions.rb:133 BigDecimal#to_s * [#7] return@:0 Fixnum#to_s # => This guy... */ if (!NIL_P(file)) { line = rb_tracearg_lineno(trace_arg); binding = rb_tracearg_binding(trace_arg); brkpnt = find_breakpoint_by_pos(breakpoints, file, line, binding); if (!NIL_P(brkpnt)) call_at_return(context, dc, rb_tracearg_return_value(trace_arg)); } } RETURN_EVENT_TEARDOWN; EVENT_TEARDOWN; }
static void end_event(VALUE trace_point, void *data) { EVENT_SETUP; RETURN_EVENT_SETUP; if ((dc->steps_out == 0) && (CTX_FL_TEST(dc, CTX_FL_STOP_ON_RET))) { reset_stepping_stop_points(dc); call_at_end(context, dc); } RETURN_EVENT_TEARDOWN; EVENT_TEARDOWN; }
static void return_event(VALUE trace_point, void *data) { EVENT_SETUP; RETURN_EVENT_SETUP; if ((dc->steps_out == 0) && (CTX_FL_TEST(dc, CTX_FL_STOP_ON_RET))) { reset_stepping_stop_points(dc); call_at_return(context, dc, rb_tracearg_return_value(trace_arg)); } RETURN_EVENT_TEARDOWN; EVENT_TEARDOWN; }
extern VALUE context_create(VALUE thread) { debug_context_t *context = ALLOC(debug_context_t); context->flags = 0; context->thnum = ++thnum_max; context->thread = thread; reset_stepping_stop_points(context); context->stop_reason = CTX_STOP_NONE; rb_debug_inspector_open(context_backtrace_set, (void *)context); context->calced_stack_size = dc_stack_size(context) + 1; if (rb_obj_class(thread) == cDebugThread) CTX_FL_SET(context, CTX_FL_IGNORE); return Data_Wrap_Struct(cContext, context_mark, 0, context); }
extern VALUE context_create(VALUE thread) { debug_context_t *context = ALLOC(debug_context_t); context->last_file = Qnil; context->last_line = Qnil; context->flags = 0; context->calced_stack_size = real_stack_size(); context->thnum = ++thnum_max; context->thread = thread; reset_stepping_stop_points(context); context->stop_reason = CTX_STOP_NONE; context->backtrace = Qnil; if (rb_obj_class(thread) == cDebugThread) CTX_FL_SET(context, CTX_FL_IGNORE); return Data_Wrap_Struct(cContext, context_mark, 0, context); }
extern VALUE context_create(VALUE thread, VALUE cDebugThread) { debug_context_t *context; VALUE locations; context = ALLOC(debug_context_t); context->stack_size = 0; locations = rb_funcall(thread, rb_intern("backtrace_locations"), 1, INT2FIX(1)); context->calced_stack_size = locations != Qnil ? (int)RARRAY_LEN(locations) : 0; context->stack = NULL; context->thnum = ++thnum_current; context->thread = thread; context->flags = 0; context->last_file = NULL; context->last_line = -1; context->stop_frame = -1; context->thread_pause = 0; reset_stepping_stop_points(context); if(rb_obj_class(thread) == cDebugThread) CTX_FL_SET(context, CTX_FL_IGNORE); return Data_Wrap_Struct(cContext, Context_mark, Context_free, context); }
static void return_event(VALUE trace_point, void *data) { EVENT_SETUP; dc->calced_stack_size--; if (dc->steps_out == 1) dc->steps = 1; else if ((dc->steps_out == 0) && (CTX_FL_TEST(dc, CTX_FL_STOP_ON_RET))) { VALUE file, line; reset_stepping_stop_points(dc); file = rb_tracearg_path(trace_arg); line = rb_tracearg_lineno(trace_arg); call_at_return(context, dc, file, line); } dc->steps_out = dc->steps_out <= 0 ? -1 : dc->steps_out - 1; EVENT_TEARDOWN; }