Example #1
0
static void
create_gc_hooks(void)
{
  int i;
  logger->hooks[0] =
    rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_GC_START,     gc_start_i,     logger);
  logger->hooks[1] =
    rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_GC_END_MARK,  gc_end_mark_i,  logger);
  logger->hooks[2] =
    rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_GC_END_SWEEP, gc_end_sweep_i, logger);
  /* mark for GC */
  for (i=0; i<3; i++) rb_gc_register_mark_object(logger->hooks[i]);
}
Example #2
0
static VALUE
install()
{
  rb_event_flag_t events =
    RUBY_INTERNAL_EVENT_GC_START    |
    RUBY_INTERNAL_EVENT_GC_END_MARK |
    RUBY_INTERNAL_EVENT_GC_END_SWEEP;

  if (_oobgc.installed)
    return Qfalse;

  if (!_oobgc.tpval) {
    _oobgc.tpval = rb_tracepoint_new(0, events, gc_event_i, (void *)0);
    rb_ivar_set(mOOB, rb_intern("tpval"), _oobgc.tpval);
  }

  rb_tracepoint_enable(_oobgc.tpval);

  /* rb_gc_stat() requires memory allocation for symbol creation only at
   * first time. If rb_gc_stat() was called during GC at first time by
   * tracepoint, memory allocation caused crash. We call rb_gc_stat() here
   * for symbol creation.
   */
  rb_gc_stat(sym_total_allocated_object);

  _oobgc.installed = 1;
  return Qtrue;
}
Example #3
0
static VALUE start_stat_server(int argc, VALUE *argv, VALUE self) {
  VALUE pub_port;
  VALUE request_port;
  int bind_result, pub_port_int, req_port_int;
  char zmq_endpoint[21], zmq_request_endpoint[21];
  server_instance = self;

  rb_scan_args(argc, argv, "02", &pub_port, &request_port);
  pub_port_int = FIX2INT(pub_port);
  req_port_int = FIX2INT(request_port);
  if(pub_port_int != 0 || request_port != 0) {
    zmq_context = zmq_ctx_new();
  }

  if(pub_port_int != 0) {
    sprintf(zmq_endpoint, "tcp://127.0.0.1:%d", FIX2INT(pub_port));
    zmq_publisher = zmq_socket(zmq_context, ZMQ_PUB);
    bind_result = zmq_bind(zmq_publisher, zmq_endpoint);
    if(bind_result != 0)
      return Qfalse;
  }

  if(req_port_int != 0) {
    sprintf(zmq_request_endpoint, "tcp://127.0.0.1:%d", FIX2INT(request_port));
    zmq_response_socket = zmq_socket(zmq_context, ZMQ_REP);
    bind_result = zmq_bind(zmq_response_socket, zmq_request_endpoint);
    if(bind_result != 0)
      return Qfalse;

    items[0].socket = zmq_response_socket;
    items[0].events = ZMQ_POLLIN;
  }

  // Creates a list which aggregates messages
  message_list_new();
  logger = get_trace_logger();
  logger->newobj_trace = rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_NEWOBJ, newobj_i, logger);
  logger->freeobj_trace = rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_FREEOBJ, freeobj_i, logger);
  rb_gc_register_mark_object(logger->newobj_trace);
  rb_gc_register_mark_object(logger->freeobj_trace);
  create_gc_hooks();

  return Qtrue;
}
Example #4
0
static VALUE
set_gc_hook(rb_event_flag_t event)
{
    VALUE tpval;
    // TODO - need to prevent applying the same tracepoint multiple times?
    tpval = rb_tracepoint_new(0, event, tracepoint_handler, 0);
    rb_tracepoint_enable(tpval);

    return tpval;
}
Example #5
0
static VALUE
stackprof_start(int argc, VALUE *argv, VALUE self)
{
    struct sigaction sa;
    struct itimerval timer;
    VALUE opts = Qnil, mode = Qnil, interval = Qnil;

    if (_stackprof.running)
	return Qfalse;

    rb_scan_args(argc, argv, "0:", &opts);

    if (RTEST(opts)) {
	mode = rb_hash_aref(opts, sym_mode);
	interval = rb_hash_aref(opts, sym_interval);
    }
    if (!RTEST(mode)) mode = sym_wall;

    if (!_stackprof.frames) {
	_stackprof.frames = st_init_numtable();
	_stackprof.overall_signals = 0;
	_stackprof.overall_samples = 0;
	_stackprof.during_gc = 0;
    }

    if (mode == sym_object) {
	if (!RTEST(interval)) interval = INT2FIX(1);

	objtracer = rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_NEWOBJ, stackprof_newobj_handler, 0);
	rb_tracepoint_enable(objtracer);
    } else if (mode == sym_wall || mode == sym_cpu) {
	if (!RTEST(interval)) interval = INT2FIX(1000);

	sa.sa_sigaction = stackprof_signal_handler;
	sa.sa_flags = SA_RESTART | SA_SIGINFO;
	sigemptyset(&sa.sa_mask);
	sigaction(mode == sym_wall ? SIGALRM : SIGPROF, &sa, NULL);

	timer.it_interval.tv_sec = 0;
	timer.it_interval.tv_usec = NUM2LONG(interval);
	timer.it_value = timer.it_interval;
	setitimer(mode == sym_wall ? ITIMER_REAL : ITIMER_PROF, &timer, 0);
    } else if (mode == sym_custom) {
	/* sampled manually */
	interval = Qnil;
    } else {
	rb_raise(rb_eArgError, "unknown profiler mode");
    }

    _stackprof.running = 1;
    _stackprof.mode = mode;
    _stackprof.interval = interval;

    return Qtrue;
}
Example #6
0
/**
 * register_tracepoint
 * Helper function to create a new tracepoint and set the instance varaible on
 * tracer if it doesn't exist already. Returns the existing tracepoint or the
 * newly created tracepoint.
 */
static VALUE
register_tracepoint(VALUE self, int event, const char *instance_variable_name, void (*call_back_func)(VALUE, void *))
{
    VALUE tracepoint = rb_iv_get(self, instance_variable_name);

    if (event && !RTEST(tracepoint)) {
        tracepoint = rb_tracepoint_new(Qnil, event, call_back_func, (void *)self);
        rb_iv_set(self, instance_variable_name, tracepoint);
    }

    return tracepoint;
}
Example #7
0
static void
register_tracepoints(VALUE self)
{
  int i;
  VALUE traces = tracepoints;

  UNUSED(self);

  if (NIL_P(traces))
  {
    int line_msk = RUBY_EVENT_LINE;
    int call_msk = RUBY_EVENT_CALL;
    int ret_msk = RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN;
    int end_msk = RUBY_EVENT_END;
    int raw_call_msk = RUBY_EVENT_C_CALL | RUBY_EVENT_B_CALL | RUBY_EVENT_CLASS;
    int raw_ret_msk = RUBY_EVENT_C_RETURN;
    int raise_msk = RUBY_EVENT_RAISE;

    VALUE tpLine = rb_tracepoint_new(Qnil, line_msk, line_event, 0);
    VALUE tpCall = rb_tracepoint_new(Qnil, call_msk, call_event, 0);
    VALUE tpReturn = rb_tracepoint_new(Qnil, ret_msk, return_event, 0);
    VALUE tpEnd = rb_tracepoint_new(Qnil, end_msk, end_event, 0);
    VALUE tpCCall = rb_tracepoint_new(Qnil, raw_call_msk, raw_call_event, 0);
    VALUE tpCReturn = rb_tracepoint_new(Qnil, raw_ret_msk, raw_return_event, 0);
    VALUE tpRaise = rb_tracepoint_new(Qnil, raise_msk, raise_event, 0);

    traces = rb_ary_new();
    rb_ary_push(traces, tpLine);
    rb_ary_push(traces, tpCall);
    rb_ary_push(traces, tpReturn);
    rb_ary_push(traces, tpEnd);
    rb_ary_push(traces, tpCCall);
    rb_ary_push(traces, tpCReturn);
    rb_ary_push(traces, tpRaise);

    tracepoints = traces;
  }

  for (i = 0; i < RARRAY_LENINT(traces); i++)
    rb_tracepoint_enable(rb_ary_entry(traces, i));
}