Class: Byebug::Context
- Inherits:
-
Object
- Object
- Byebug::Context
- Defined in:
- lib/byebug/context.rb,
ext/byebug/context.c
Overview
Mantains context information for the debugger and it’s the main communication point between the library and the C-extension through the at_breakpoint, at_catchpoint, at_tracing, at_line and at_return callbacks
Class Method Summary collapse
Instance Method Summary collapse
- #at_breakpoint(brkpnt) ⇒ Object
- #at_catchpoint(excpt) ⇒ Object
- #at_line(file, line) ⇒ Object
- #at_return(file, line) ⇒ Object
- #at_tracing(file, line) ⇒ Object
- #c_frame_args(frame_no) ⇒ Object
- #calced_stack_size ⇒ Object
- #dead? ⇒ Boolean
- #frame_args(frame_no = 0) ⇒ Object
-
#frame_binding(frame_position = 0) ⇒ Binding
Returns frame’s binding.
-
#frame_class(frame_position = 0) ⇒ Binding
Returns frame’s defined class.
-
#frame_file(frame_position = 0) ⇒ String
Returns the name of the file in the frame.
-
#frame_line(frame_position) ⇒ Integer
Returns the line number in the file.
- #frame_locals(frame_no = 0) ⇒ Object
-
#frame_method(frame_position = 0) ⇒ Object
Returns the sym of the called method.
-
#frame_self(frame_postion = 0) ⇒ Object
Returns self object of the frame.
- #handler ⇒ Object
- #ignored? ⇒ Boolean
- #interrupt ⇒ Object
-
#resume ⇒ nil
Resumes thread from the suspended mode.
- #ruby_frame_args(bind) ⇒ Object
-
#step_into(steps, force = false) ⇒ Object
Stops the current context after a number of
steps
are made. -
#step_out(n_frames = 1, force = false) ⇒ Object
Stops after
n_frames
frames are finished. -
#step_over(lines, frame = 0, force = false) ⇒ Object
Steps over
lines
lines. - #stop_reason ⇒ Object
-
#suspend ⇒ nil
Suspends the thread when it is running.
-
#suspended? ⇒ Boolean
Returns
true
if the thread is suspended by debugger. - #thnum ⇒ Object
- #thread ⇒ Object
-
#tracing ⇒ Boolean
Returns the tracing flag for the current context.
-
#tracing=(bool) ⇒ Object
Controls the tracing for this context.
Class Method Details
.ignored(path) ⇒ Object
22 23 24 |
# File 'lib/byebug/context.rb', line 22 def ignored(path) IGNORED_FILES.include?(path) end |
.stack_size(byebug_frames = false) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/byebug/context.rb', line 9 def stack_size(byebug_frames = false) backtrace = Thread.current.backtrace_locations(0) return 0 unless backtrace unless byebug_frames backtrace = backtrace.drop_while { |l| !ignored(l.path) } .drop_while { |l| ignored(l.path) } .take_while { |l| !ignored(l.path) } end backtrace.size end |
Instance Method Details
#at_breakpoint(brkpnt) ⇒ Object
67 68 69 |
# File 'lib/byebug/context.rb', line 67 def at_breakpoint(brkpnt) handler.at_breakpoint(self, brkpnt) end |
#at_catchpoint(excpt) ⇒ Object
71 72 73 |
# File 'lib/byebug/context.rb', line 71 def at_catchpoint(excpt) handler.at_catchpoint(self, excpt) end |
#at_line(file, line) ⇒ Object
79 80 81 |
# File 'lib/byebug/context.rb', line 79 def at_line(file, line) handler.at_line(self, file, line) unless IGNORED_FILES.include?(file) end |
#at_return(file, line) ⇒ Object
83 84 85 |
# File 'lib/byebug/context.rb', line 83 def at_return(file, line) handler.at_return(self, file, line) end |
#at_tracing(file, line) ⇒ Object
75 76 77 |
# File 'lib/byebug/context.rb', line 75 def at_tracing(file, line) handler.at_tracing(self, file, line) end |
#c_frame_args(frame_no) ⇒ Object
37 38 39 40 41 |
# File 'lib/byebug/context.rb', line 37 def c_frame_args(frame_no) myself = frame_self frame_no return [] unless myself.to_s != 'main' myself.send(:method, frame_method(frame_no)).parameters end |
#calced_stack_size ⇒ Object
#dead? ⇒ Boolean
#frame_args(frame_no = 0) ⇒ Object
54 55 56 57 58 59 60 61 |
# File 'lib/byebug/context.rb', line 54 def frame_args(frame_no = 0) bind = frame_binding frame_no if bind.nil? c_frame_args frame_no else ruby_frame_args bind end end |
#frame_binding(frame_position = 0) ⇒ Binding
Returns frame’s binding.
201 202 203 204 205 206 207 |
# File 'ext/byebug/context.c', line 201
static VALUE
Context_frame_binding(int argc, VALUE *argv, VALUE self)
{
FRAME_SETUP
return dc_frame_binding(context, frame_n);
}
|
#frame_class(frame_position = 0) ⇒ Binding
Returns frame’s defined class.
215 216 217 218 219 220 221 |
# File 'ext/byebug/context.c', line 215
static VALUE
Context_frame_class(int argc, VALUE *argv, VALUE self)
{
FRAME_SETUP
return dc_frame_class(context, frame_n);
}
|
#frame_file(frame_position = 0) ⇒ String
Returns the name of the file in the frame.
229 230 231 232 233 234 235 236 237 238 239 |
# File 'ext/byebug/context.c', line 229
static VALUE
Context_frame_file(int argc, VALUE *argv, VALUE self)
{
VALUE loc;
FRAME_SETUP
loc = dc_frame_location(context, frame_n);
return rb_funcall(loc, rb_intern("path"), 0);
}
|
#frame_line(frame_position) ⇒ Integer
Returns the line number in the file.
247 248 249 250 251 252 253 254 255 256 257 |
# File 'ext/byebug/context.c', line 247
static VALUE
Context_frame_line(int argc, VALUE *argv, VALUE self)
{
VALUE loc;
FRAME_SETUP
loc = dc_frame_location(context, frame_n);
return rb_funcall(loc, rb_intern("lineno"), 0);
}
|
#frame_locals(frame_no = 0) ⇒ Object
32 33 34 35 |
# File 'lib/byebug/context.rb', line 32 def frame_locals(frame_no = 0) bind = frame_binding frame_no eval 'local_variables.inject({}){|h, v| h[v] = eval(v.to_s); h}', bind end |
#frame_method(frame_position = 0) ⇒ Object
Returns the sym of the called method.
265 266 267 268 269 270 271 272 273 274 275 |
# File 'ext/byebug/context.c', line 265
static VALUE
Context_frame_method(int argc, VALUE *argv, VALUE self)
{
VALUE loc;
FRAME_SETUP
loc = dc_frame_location(context, frame_n);
return rb_str_intern(rb_funcall(loc, rb_intern("label"), 0));
}
|
#frame_self(frame_postion = 0) ⇒ Object
Returns self object of the frame.
283 284 285 286 287 288 289 |
# File 'ext/byebug/context.c', line 283
static VALUE
Context_frame_self(int argc, VALUE *argv, VALUE self)
{
FRAME_SETUP
return dc_frame_self(context, frame_n);
}
|
#handler ⇒ Object
63 64 65 |
# File 'lib/byebug/context.rb', line 63 def handler Byebug.handler || fail('No interface loaded') end |
#ignored? ⇒ Boolean
#interrupt ⇒ Object
28 29 30 |
# File 'lib/byebug/context.rb', line 28 def interrupt step_into 1 end |
#resume ⇒ nil
Resumes thread from the suspended mode.
323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'ext/byebug/context.c', line 323
static VALUE
Context_resume(VALUE self)
{
debug_context_t *context;
Data_Get_Struct(self, debug_context_t, context);
if (!CTX_FL_TEST(context, CTX_FL_SUSPEND))
rb_raise(rb_eRuntimeError, "Thread is not suspended.");
context_resume_0(context);
return Qnil;
}
|
#ruby_frame_args(bind) ⇒ Object
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/byebug/context.rb', line 43 def ruby_frame_args(bind) return [] unless eval '__method__', bind begin eval 'self.method(__method__).parameters', bind rescue NameError => e puts "WARNING: Got exception #{e.class}: \"#{e.}\" " \ 'while retreving parameters from frame' return [] end end |
#step_into(steps, force = false) ⇒ Object
Stops the current context after a number of steps
are made. force
parameter (if true) ensures that the cursor moves away from the current line.
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
# File 'ext/byebug/context.c', line 392
static VALUE
Context_step_into(int argc, VALUE *argv, VALUE self)
{
VALUE steps, force;
debug_context_t *context;
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, context);
context->steps = FIX2INT(steps);
if (RTEST(force))
CTX_FL_SET(context, CTX_FL_FORCE_MOVE);
else
CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE);
return steps;
}
|
#step_out(n_frames = 1, force = false) ⇒ Object
Stops after n_frames
frames are finished. force
parameter (if true) ensures that the execution will stop in the specified frame even when there are no more instructions to run. In that case, it will stop when the return event for that frame is triggered.
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
# File 'ext/byebug/context.c', line 422
static VALUE
Context_step_out(int argc, VALUE *argv, VALUE self)
{
int n_args, n_frames;
VALUE v_frames, force;
debug_context_t *context;
n_args = rb_scan_args(argc, argv, "02", &v_frames, &force);
n_frames = n_args == 0 ? 1 : FIX2INT(v_frames);
Data_Get_Struct(self, debug_context_t, context);
if (n_frames < 0 || n_frames > context->calced_stack_size)
rb_raise(rb_eRuntimeError,
"You wan't to finish %d frames, but stack size is only %d",
n_frames, context->calced_stack_size);
context->steps_out = n_frames;
if (n_args == 2 && RTEST(force))
CTX_FL_SET(context, CTX_FL_STOP_ON_RET);
else
CTX_FL_UNSET(context, CTX_FL_STOP_ON_RET);
return Qnil;
}
|
#step_over(lines, frame = 0, force = false) ⇒ Object
Steps over lines
lines. Make step over operation on frame
, by default the newest frame. force
parameter (if true) ensures that the cursor moves away from the current line.
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 |
# File 'ext/byebug/context.c', line 457
static VALUE
Context_step_over(int argc, VALUE *argv, VALUE self)
{
int n_args, frame;
VALUE lines, v_frame, force;
debug_context_t *context;
Data_Get_Struct(self, debug_context_t, context);
if (context->calced_stack_size == 0)
rb_raise(rb_eRuntimeError, "No frames collected.");
n_args = rb_scan_args(argc, argv, "12", &lines, &v_frame, &force);
frame = n_args == 1 ? 0 : FIX2INT(v_frame);
if (frame < 0 || frame >= context->calced_stack_size)
rb_raise(rb_eRuntimeError,
"Destination frame (%d) is out of range (%d)",
frame, context->calced_stack_size);
context->lines = FIX2INT(lines);
context->dest_frame = context->calced_stack_size - frame;
if (n_args == 3 && RTEST(force))
CTX_FL_SET(context, CTX_FL_FORCE_MOVE);
else
CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE);
return Qnil;
}
|
#stop_reason ⇒ Object
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
# File 'ext/byebug/context.c', line 356
static VALUE
Context_stop_reason(VALUE self)
{
debug_context_t *context;
const char *symbol;
Data_Get_Struct(self, debug_context_t, context);
if (CTX_FL_TEST(context, CTX_FL_DEAD))
symbol = "post-mortem";
else switch (context->stop_reason)
{
case CTX_STOP_STEP:
symbol = "step";
break;
case CTX_STOP_BREAKPOINT:
symbol = "breakpoint";
break;
case CTX_STOP_CATCHPOINT:
symbol = "catchpoint";
break;
case CTX_STOP_NONE:
default:
symbol = "none";
}
return ID2SYM(rb_intern(symbol));
}
|
#suspend ⇒ nil
Suspends the thread when it is running.
509 510 511 512 513 514 515 516 517 518 519 520 |
# File 'ext/byebug/context.c', line 509
static VALUE
Context_suspend(VALUE self)
{
debug_context_t *context;
Data_Get_Struct(self, debug_context_t, context);
if (CTX_FL_TEST(context, CTX_FL_SUSPEND))
rb_raise(rb_eRuntimeError, "Already suspended.");
context_suspend_0(context);
return Qnil;
}
|
#suspended? ⇒ Boolean
Returns true
if the thread is suspended by debugger.
528 529 530 531 532 533 534 535 |
# File 'ext/byebug/context.c', line 528
static VALUE
Context_is_suspended(VALUE self)
{
debug_context_t *context;
Data_Get_Struct(self, debug_context_t, context);
return CTX_FL_TEST(context, CTX_FL_SUSPEND) ? Qtrue : Qfalse;
}
|
#thnum ⇒ Object
#thread ⇒ Object
#tracing ⇒ Boolean
Returns the tracing flag for the current context.
570 571 572 573 574 575 576 577 |
# File 'ext/byebug/context.c', line 570
static VALUE
Context_tracing(VALUE self)
{
debug_context_t *context;
Data_Get_Struct(self, debug_context_t, context);
return CTX_FL_TEST(context, CTX_FL_TRACING) ? Qtrue : Qfalse;
}
|
#tracing=(bool) ⇒ Object
Controls the tracing for this context.
585 586 587 588 589 590 591 592 593 594 595 596 597 |
# File 'ext/byebug/context.c', line 585
static VALUE
Context_set_tracing(VALUE self, VALUE value)
{
debug_context_t *context;
Data_Get_Struct(self, debug_context_t, context);
if (RTEST(value))
CTX_FL_SET(context, CTX_FL_TRACING);
else
CTX_FL_UNSET(context, CTX_FL_TRACING);
return value;
}
|