Ejemplo n.º 1
0
static VALUE
Context_step_over(int argc, VALUE *argv, VALUE self)
{
  VALUE lines, frame, force;
  debug_context_t *context;

  Data_Get_Struct(self, debug_context_t, context);
  if(context->stack_size == 0)
    rb_raise(rb_eRuntimeError, "No frames collected.");

  rb_scan_args(argc, argv, "12", &lines, &frame, &force);
  context->stop_line = FIX2INT(lines);
  CTX_FL_UNSET(context, CTX_FL_STEPPED);
  if (frame == Qnil)
  {
    context->dest_frame = context->calced_stack_size;
  }
  else
  {
    if (FIX2INT(frame) < 0 && FIX2INT(frame) >= context->calced_stack_size)
      rb_raise(rb_eRuntimeError, "Destination frame is out of range.");
    context->dest_frame = context->calced_stack_size - FIX2INT(frame);
  }
  if(RTEST(force))
    CTX_FL_SET(context, CTX_FL_FORCE_MOVE);
  else
    CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE);

  return Qnil;
}
Ejemplo n.º 2
0
/*
 *  call-seq:
 *    context.step_out(n_frames = 1, force = false)
 *
 *  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.
 */
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 want 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;
}
Ejemplo n.º 3
0
/*
 *  call-seq:
 *    context.step_into(steps, frame = 0)
 *
 *  Stops the current context after a number of +steps+ are made from frame
 *  +frame+ (by default the newest one).
 */
static VALUE
Context_step_into(int argc, VALUE * argv, VALUE self)
{
  VALUE steps, v_frame;
  int n_args, from_frame;
  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, "11", &steps, &v_frame);

  if (FIX2INT(steps) <= 0)
    rb_raise(rb_eRuntimeError, "Steps argument can't be negative.");

  from_frame = n_args == 1 ? 0 : FIX2INT(v_frame);

  if (from_frame < 0 || from_frame >= context->calced_stack_size)
    rb_raise(rb_eRuntimeError, "Destination frame (%d) is out of range (%d)",
             from_frame, context->calced_stack_size);
  else if (from_frame > 0)
    CTX_FL_SET(context, CTX_FL_IGNORE_STEPS);

  context->steps = FIX2INT(steps);
  context->dest_frame = context->calced_stack_size - from_frame;

  return steps;
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
/*
 *  call-seq:
 *    context.suspend -> nil
 *
 *  Suspends the thread when it is running.
 */
static VALUE
Context_suspend(VALUE self)
{
  VALUE status;
  debug_context_t *context;

  Data_Get_Struct(self, debug_context_t, context);

  status = rb_funcall(context->thread, rb_intern("status"), 0);

  if (rb_str_cmp(status, rb_str_new2("run")) == 0)
    CTX_FL_SET(context, CTX_FL_WAS_RUNNING);
  else if (rb_str_cmp(status, rb_str_new2("sleep")) == 0)
    CTX_FL_UNSET(context, CTX_FL_WAS_RUNNING);
  else
    return Qnil;

  CTX_FL_SET(context, CTX_FL_SUSPEND);

  return Qnil;
}
Ejemplo n.º 6
0
/*
 *  call-seq:
 *    context.tracing = bool
 *
 *  Controls the tracing for this context.
 */
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;
}
Ejemplo n.º 7
0
/*
 *  call-seq:
 *    context.switch -> nil
 *
 *  Switches execution to this context.
 */
static VALUE
Context_switch(VALUE self)
{
  debug_context_t *context;

  Data_Get_Struct(self, debug_context_t, context);

  next_thread = context->thread;

  context->steps = 1;
  context->steps_out = 0;
  CTX_FL_SET(context, CTX_FL_STOP_ON_RET);

  return Qnil;
}
Ejemplo n.º 8
0
/*
 * Holds thread execution while another thread is active.
 *
 * Thanks to this, all threads are "frozen" while the user is typing commands.
 */
void
acquire_lock(debug_context_t * dc)
{
  while ((!NIL_P(locker) && locker != rb_thread_current())
         || CTX_FL_TEST(dc, CTX_FL_SUSPEND))
  {
    add_to_locked(rb_thread_current());
    rb_thread_stop();

    if (CTX_FL_TEST(dc, CTX_FL_SUSPEND))
      CTX_FL_SET(dc, CTX_FL_WAS_RUNNING);
  }

  locker = rb_thread_current();
}
Ejemplo n.º 9
0
static VALUE
Context_stop_next(int argc, VALUE *argv, VALUE self)
{
  VALUE steps;
  VALUE 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->stop_next = FIX2INT(steps);
  if(RTEST(force))
      CTX_FL_SET(context, CTX_FL_FORCE_MOVE);
  else
      CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE);

  return steps;
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
0
Archivo: byebug.c Proyecto: Xifip/modr
static int
trace_common(rb_trace_arg_t *trace_arg, debug_context_t *dc)
{
  /* return if thread marked as 'ignored', like byebug's control thread */
  if (CTX_FL_TEST(dc, CTX_FL_IGNORE))
  {
    cleanup(dc);
    return 0;
  }

  halt_while_other_thread_is_active(dc);

  /* Get the lock! */
  locker = rb_thread_current();

  /* Many events per line, but only *one* breakpoint */
  if (dc->last_line != rb_tracearg_lineno(trace_arg) ||
      dc->last_file != rb_tracearg_path(trace_arg))
  {
    CTX_FL_SET(dc, CTX_FL_ENABLE_BKPT);
  }

  return 1;
}