Class | Debugger::Context |
In: |
lib/ruby-debug-base.rb
ext/ruby_debug.c |
Parent: | Object |
Document-class: Context
The Debugger module keeps a single instance of this class for each Ruby thread. It contains a call-stack information, thread information, breakpoint information and the reason the program is stopped.
frame_binding | -> | __c_frame_binding |
Returns a context-specific temporary Breakpoint object.
/* * call-seq: * context.breakpoint -> Breakpoint * * Returns a context-specific temporary Breakpoint object. */ VALUE context_breakpoint(VALUE self) { debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); return debug_context->breakpoint; }
Returns true if context doesn‘t represent a live context and is created during post-mortem exception handling.
/* * call-seq: * context.dead? -> bool * * Returns +true+ if context doesn't represent a live context and is created * during post-mortem exception handling. */ static VALUE context_dead(VALUE self) { debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); return CTX_FL_TEST(debug_context, CTX_FL_DEAD) ? Qtrue : Qfalse; }
Returns frame‘s argument parameters
/* * call-seq: * context.frame_args(frame_position=0) -> list * * Returns frame's argument parameters */ static VALUE context_frame_args(int argc, VALUE *argv, VALUE self) { VALUE frame; debug_context_t *debug_context; debug_frame_t *debug_frame; debug_check_started(); frame = optional_frame_position(argc, argv); Data_Get_Struct(self, debug_context_t, debug_context); debug_frame = GET_FRAME; if(debug_frame->dead) return debug_frame->info.copy.args; else return context_copy_args(debug_frame); }
Returns info saved about call arguments (if any saved).
/* * call-seq: * context.frame_args_info(frame_position=0) -> list if track_frame_args or nil otherwise * * Returns info saved about call arguments (if any saved). */ static VALUE context_frame_args_info(int argc, VALUE *argv, VALUE self) { VALUE frame; debug_context_t *debug_context; debug_check_started(); frame = optional_frame_position(argc, argv); Data_Get_Struct(self, debug_context_t, debug_context); return RTEST(track_frame_args) ? GET_FRAME->arg_ary : Qnil; }
# File lib/ruby-debug-base.rb, line 21 21: def frame_binding(frame) 22: __c_frame_binding(frame) || hbinding(frame) 23: end
Returns frame‘s binding.
/* * call-seq: * context.frame_binding(frame_position=0) -> binding * * Returns frame's binding. */ static VALUE context_frame_binding(int argc, VALUE *argv, VALUE self) { VALUE frame; debug_context_t *debug_context; debug_check_started(); frame = optional_frame_position(argc, argv); Data_Get_Struct(self, debug_context_t, debug_context); return GET_FRAME->binding; }
Returns the real class of the frame. It could be different than context.frame_self(frame).class
/* * call-seq: * context.frame_class(frame_position) -> obj * * Returns the real class of the frame. * It could be different than context.frame_self(frame).class */ static VALUE context_frame_class(int argc, VALUE *argv, VALUE self) { VALUE frame; debug_context_t *debug_context; debug_frame_t *debug_frame; VALUE klass; debug_check_started(); frame = optional_frame_position(argc, argv); Data_Get_Struct(self, debug_context_t, debug_context); debug_frame = GET_FRAME; if(CTX_FL_TEST(debug_context, CTX_FL_DEAD)) return Qnil; #if RUBY_VERSION_CODE >= 190 klass = debug_frame->info.runtime.frame->this_class; #else klass = debug_frame->info.runtime.frame->last_class; #endif klass = real_class(klass); if(TYPE(klass) == T_CLASS || TYPE(klass) == T_MODULE) return klass; return Qnil; }
Returns the name of the file.
/* * call-seq: * context.frame_file(frame_position) -> string * * Returns the name of the file. */ static VALUE context_frame_file(int argc, VALUE *argv, VALUE self) { VALUE frame; debug_context_t *debug_context; debug_check_started(); frame = optional_frame_position(argc, argv); Data_Get_Struct(self, debug_context_t, debug_context); return rb_str_new2(GET_FRAME->file); }
Returns the sym of the called method.
/* * call-seq: * context.frame_method(frame_position=0) -> sym * * Returns the sym of the called method. */ static VALUE context_frame_id(int argc, VALUE *argv, VALUE self) { VALUE frame; debug_context_t *debug_context; ID id; debug_check_started(); frame = optional_frame_position(argc, argv); Data_Get_Struct(self, debug_context_t, debug_context); id = GET_FRAME->id; return id ? ID2SYM(id): Qnil; }
Returns the line number in the file.
/* * call-seq: * context.frame_line(frame_position) -> int * * Returns the line number in the file. */ static VALUE context_frame_line(int argc, VALUE *argv, VALUE self) { VALUE frame; debug_context_t *debug_context; debug_check_started(); frame = optional_frame_position(argc, argv); Data_Get_Struct(self, debug_context_t, debug_context); return INT2FIX(GET_FRAME->line); }
Returns frame‘s local variables.
/* * call-seq: * context.frame_locals(frame) -> hash * * Returns frame's local variables. */ static VALUE context_frame_locals(int argc, VALUE *argv, VALUE self) { VALUE frame; debug_context_t *debug_context; debug_frame_t *debug_frame; debug_check_started(); frame = optional_frame_position(argc, argv); Data_Get_Struct(self, debug_context_t, debug_context); debug_frame = GET_FRAME; if(debug_frame->dead) return debug_frame->info.copy.locals; else return context_copy_locals(debug_frame); }
Returns the sym of the called method.
/* * call-seq: * context.frame_method(frame_position=0) -> sym * * Returns the sym of the called method. */ static VALUE context_frame_id(int argc, VALUE *argv, VALUE self) { VALUE frame; debug_context_t *debug_context; ID id; debug_check_started(); frame = optional_frame_position(argc, argv); Data_Get_Struct(self, debug_context_t, debug_context); id = GET_FRAME->id; return id ? ID2SYM(id): Qnil; }
Returns self object of the frame.
/* * call-seq: * context.frame_self(frame_postion=0) -> obj * * Returns self object of the frame. */ static VALUE context_frame_self(int argc, VALUE *argv, VALUE self) { VALUE frame; debug_context_t *debug_context; debug_frame_t *debug_frame; debug_check_started(); frame = optional_frame_position(argc, argv); Data_Get_Struct(self, debug_context_t, debug_context); debug_frame = GET_FRAME; return debug_frame->self; }
Returns the ignore flag for the current context.
/* * call-seq: * context.ignored? -> bool * * Returns the ignore flag for the current context. */ static VALUE context_ignored(VALUE self) { debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); return CTX_FL_TEST(debug_context, CTX_FL_IGNORE) ? Qtrue : Qfalse; }
Resumes the thread from the suspended mode.
/* * call-seq: * context.resume -> nil * * Resumes the thread from the suspended mode. */ static VALUE context_resume(VALUE self) { debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); if(!CTX_FL_TEST(debug_context, CTX_FL_SUSPEND)) rb_raise(rb_eRuntimeError, "Thread is not suspended."); context_resume_0(debug_context); return Qnil; }
Sets a context-specific temporary breakpoint, which can be used to implement ‘Run to Cursor’ debugger function. When this breakpoint is reached, it will be cleared out.
source is a name of a file or a class. pos is a line number or a method name if source is a class name. condition is a string which is evaluated to true when this breakpoint is activated.
/* * call-seq: * context.set_breakpoint(source, pos, condition = nil) -> breakpoint * * Sets a context-specific temporary breakpoint, which can be used to implement * 'Run to Cursor' debugger function. When this breakpoint is reached, it will be * cleared out. * * <i>source</i> is a name of a file or a class. * <i>pos</i> is a line number or a method name if <i>source</i> is a class name. * <i>condition</i> is a string which is evaluated to +true+ when this breakpoint * is activated. */ VALUE context_set_breakpoint(int argc, VALUE *argv, VALUE self) { VALUE result; debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); result = create_breakpoint_from_args(argc, argv, 0); debug_context->breakpoint = result; return result; }
Returns the size of the context stack.
/* * call-seq: * context.stack_size-> int * * Returns the size of the context stack. */ static VALUE context_stack_size(VALUE self) { debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); return INT2FIX(debug_context->stack_size); }
Stops the current context after a number of steps are made. force parameter (if true) ensures that the cursor moves from the current line.
/* * call-seq: * context.step(steps, force = false) * * Stops the current context after a number of +steps+ are made. * +force+ parameter (if true) ensures that the cursor moves from the current line. */ static VALUE context_stop_next(int argc, VALUE *argv, VALUE self) { VALUE steps, force; debug_context_t *debug_context; debug_check_started(); rb_scan_args(argc, argv, "11", &steps, &force); if(FIX2INT(steps) < 0) rb_raise(rb_eRuntimeError, "Steps argument can't be negative."); Data_Get_Struct(self, debug_context_t, debug_context); debug_context->stop_next = FIX2INT(steps); if(RTEST(force)) CTX_FL_SET(debug_context, CTX_FL_FORCE_MOVE); else CTX_FL_UNSET(debug_context, CTX_FL_FORCE_MOVE); return steps; }
Steps over a steps number of times. Make step over operation on frame, by default the current frame. force parameter (if true) ensures that the cursor moves from the current line.
/* * call-seq: * context.step_over(steps, frame = nil, force = false) * * Steps over a +steps+ number of times. * Make step over operation on +frame+, by default the current frame. * +force+ parameter (if true) ensures that the cursor moves from the current line. */ static VALUE context_step_over(int argc, VALUE *argv, VALUE self) { VALUE lines, frame, force; debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); if(debug_context->stack_size == 0) rb_raise(rb_eRuntimeError, "No frames collected."); rb_scan_args(argc, argv, "12", &lines, &frame, &force); debug_context->stop_line = FIX2INT(lines); CTX_FL_UNSET(debug_context, CTX_FL_STEPPED); if(frame == Qnil) { debug_context->dest_frame = debug_context->stack_size; } else { if(FIX2INT(frame) < 0 && FIX2INT(frame) >= debug_context->stack_size) rb_raise(rb_eRuntimeError, "Destination frame is out of range."); debug_context->dest_frame = debug_context->stack_size - FIX2INT(frame); } if(RTEST(force)) CTX_FL_SET(debug_context, CTX_FL_FORCE_MOVE); else CTX_FL_UNSET(debug_context, CTX_FL_FORCE_MOVE); return Qnil; }
Stops when a frame with number frame is activated. Implements finish and next commands.
/* * call-seq: * context.stop_frame(frame) * * Stops when a frame with number +frame+ is activated. Implements +finish+ and +next+ commands. */ static VALUE context_stop_frame(VALUE self, VALUE frame) { debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); if(FIX2INT(frame) < 0 && FIX2INT(frame) >= debug_context->stack_size) rb_raise(rb_eRuntimeError, "Stop frame is out of range."); debug_context->stop_frame = debug_context->stack_size - FIX2INT(frame); return frame; }
Stops the current context after a number of steps are made. force parameter (if true) ensures that the cursor moves from the current line.
/* * call-seq: * context.step(steps, force = false) * * Stops the current context after a number of +steps+ are made. * +force+ parameter (if true) ensures that the cursor moves from the current line. */ static VALUE context_stop_next(int argc, VALUE *argv, VALUE self) { VALUE steps, force; debug_context_t *debug_context; debug_check_started(); rb_scan_args(argc, argv, "11", &steps, &force); if(FIX2INT(steps) < 0) rb_raise(rb_eRuntimeError, "Steps argument can't be negative."); Data_Get_Struct(self, debug_context_t, debug_context); debug_context->stop_next = FIX2INT(steps); if(RTEST(force)) CTX_FL_SET(debug_context, CTX_FL_FORCE_MOVE); else CTX_FL_UNSET(debug_context, CTX_FL_FORCE_MOVE); return steps; }
Returns the reason for the stop. It maybe of the following values: :initial, :step, :breakpoint, :catchpoint, :post-mortem
/* * call-seq: * context.stop_reason -> sym * * Returns the reason for the stop. It maybe of the following values: * :initial, :step, :breakpoint, :catchpoint, :post-mortem */ static VALUE context_stop_reason(VALUE self) { debug_context_t *debug_context; char * sym_name; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); switch(debug_context->stop_reason) { case CTX_STOP_STEP: sym_name = "step"; break; case CTX_STOP_BREAKPOINT: sym_name = "breakpoint"; break; case CTX_STOP_CATCHPOINT: sym_name = "catchpoint"; break; case CTX_STOP_NONE: default: sym_name = "none"; } if(CTX_FL_TEST(debug_context, CTX_FL_DEAD)) sym_name = "post-mortem"; return ID2SYM(rb_intern(sym_name)); }
Suspends the thread when it is running.
/* * call-seq: * context.suspend -> nil * * Suspends the thread when it is running. */ static VALUE context_suspend(VALUE self) { debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); if(CTX_FL_TEST(debug_context, CTX_FL_SUSPEND)) rb_raise(rb_eRuntimeError, "Already suspended."); context_suspend_0(debug_context); return Qnil; }
Returns true if the thread is suspended by debugger.
/* * call-seq: * context.suspended? -> bool * * Returns +true+ if the thread is suspended by debugger. */ static VALUE context_is_suspended(VALUE self) { debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); return CTX_FL_TEST(debug_context, CTX_FL_SUSPEND) ? Qtrue : Qfalse; }
Returns the context‘s number.
/* * call-seq: * context.thnum -> int * * Returns the context's number. */ static VALUE context_thnum(VALUE self) { debug_context_t *debug_context; Data_Get_Struct(self, debug_context_t, debug_context); return INT2FIX(debug_context->thnum); }
Returns a thread this context is associated with.
/* * call-seq: * context.thread -> thread * * Returns a thread this context is associated with. */ static VALUE context_thread(VALUE self) { debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); return context_thread_0(debug_context); }
Returns the tracing flag for the current context.
/* * call-seq: * context.tracing -> bool * * Returns the tracing flag for the current context. */ static VALUE context_tracing(VALUE self) { debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); return CTX_FL_TEST(debug_context, CTX_FL_TRACING) ? Qtrue : Qfalse; }
Controls the tracing for this context.
/* * call-seq: * context.tracing = bool * * Controls the tracing for this context. */ static VALUE context_set_tracing(VALUE self, VALUE value) { debug_context_t *debug_context; debug_check_started(); Data_Get_Struct(self, debug_context_t, debug_context); if(RTEST(value)) CTX_FL_SET(debug_context, CTX_FL_TRACING); else CTX_FL_UNSET(debug_context, CTX_FL_TRACING); return value; }