void stackprof_record_sample() { int num, i; VALUE prev_frame = Qnil; _stackprof.overall_samples++; num = rb_profile_frames(0, sizeof(_stackprof.frames_buffer), _stackprof.frames_buffer, _stackprof.lines_buffer); for (i = 0; i < num; i++) { int line = _stackprof.lines_buffer[i]; VALUE frame = _stackprof.frames_buffer[i]; frame_data_t *frame_data = sample_for(frame); frame_data->total_samples++; if (i == 0) { frame_data->caller_samples++; } else { if (!frame_data->edges) frame_data->edges = st_init_numtable(); st_numtable_increment(frame_data->edges, (st_data_t)prev_frame, 1); } if (line > 0) { if (!frame_data->lines) frame_data->lines = st_init_numtable(); size_t half = (size_t)1<<(8*SIZEOF_SIZE_T/2); size_t increment = i == 0 ? half + 1 : half; st_numtable_increment(frame_data->lines, (st_data_t)line, increment); } prev_frame = frame; } }
static void sampling_job_handler(void *data_unused) { int start = 0; int lines[BUF_SIZE]; VALUE buff[BUF_SIZE]; VALUE rb_method_name, rb_label, rb_file, rb_singleton_method; int i, is_singleton; char *method_name, *label, *file; unsigned long line, thread_id; rbkit_cpu_sample *sample = malloc(sizeof(rbkit_cpu_sample)); int collected_size = rb_profile_frames(start, sizeof(buff) / sizeof(VALUE), buff, lines); rbkit_frame_data *frame_data = malloc(sizeof(rbkit_frame_data) * collected_size); sample->frames = frame_data; sample->frame_count = collected_size; for (i=0; i<collected_size; i++) { rb_method_name = rb_profile_frame_method_name(buff[i]); if(NIL_P(rb_method_name)) { method_name = NULL; } else { method_name = StringValueCStr(rb_method_name); } frame_data[i].method_name = method_name; rb_label = rb_profile_frame_full_label(buff[i]); label = StringValueCStr(rb_label); frame_data[i].label = label; rb_file = rb_profile_frame_absolute_path(buff[i]); if(NIL_P(rb_file)) rb_file = rb_profile_frame_path(buff[i]); file = StringValueCStr(rb_file); frame_data[i].file = file; line = FIX2ULONG(rb_profile_frame_first_lineno(buff[i])); frame_data[i].line = line; rb_singleton_method = rb_profile_frame_singleton_method_p(buff[i]); is_singleton = rb_singleton_method == Qtrue; frame_data[i].is_singleton_method = is_singleton; thread_id = FIX2ULONG(rb_obj_id(rb_thread_current())); frame_data[i].thread_id = thread_id; } queue_cpu_sample_for_sending(sample); free(frame_data); free(sample); }
void stackprof_record_sample() { int num, i, n; VALUE prev_frame = Qnil; _stackprof.overall_samples++; num = rb_profile_frames(0, sizeof(_stackprof.frames_buffer) / sizeof(VALUE), _stackprof.frames_buffer, _stackprof.lines_buffer); if (_stackprof.raw) { int found = 0; if (!_stackprof.raw_samples) { _stackprof.raw_samples_capa = num * 100; _stackprof.raw_samples = malloc(sizeof(VALUE) * _stackprof.raw_samples_capa); } if (_stackprof.raw_samples_capa <= _stackprof.raw_samples_len + num) { _stackprof.raw_samples_capa *= 2; _stackprof.raw_samples = realloc(_stackprof.raw_samples, sizeof(VALUE) * _stackprof.raw_samples_capa); } if (_stackprof.raw_samples_len > 0 && _stackprof.raw_samples[_stackprof.raw_sample_index] == (VALUE)num) { for (i = num-1, n = 0; i >= 0; i--, n++) { VALUE frame = _stackprof.frames_buffer[i]; if (_stackprof.raw_samples[_stackprof.raw_sample_index + 1 + n] != frame) break; } if (i == -1) { _stackprof.raw_samples[_stackprof.raw_samples_len-1] += 1; found = 1; } } if (!found) { _stackprof.raw_sample_index = _stackprof.raw_samples_len; _stackprof.raw_samples[_stackprof.raw_samples_len++] = (VALUE)num; for (i = num-1; i >= 0; i--) { VALUE frame = _stackprof.frames_buffer[i]; _stackprof.raw_samples[_stackprof.raw_samples_len++] = frame; } _stackprof.raw_samples[_stackprof.raw_samples_len++] = (VALUE)1; } } for (i = 0; i < num; i++) { int line = _stackprof.lines_buffer[i]; VALUE frame = _stackprof.frames_buffer[i]; frame_data_t *frame_data = sample_for(frame); frame_data->total_samples++; if (i == 0) { frame_data->caller_samples++; } else if (_stackprof.aggregate) { if (!frame_data->edges) frame_data->edges = st_init_numtable(); st_numtable_increment(frame_data->edges, (st_data_t)prev_frame, 1); } if (_stackprof.aggregate && line > 0) { if (!frame_data->lines) frame_data->lines = st_init_numtable(); size_t half = (size_t)1<<(8*SIZEOF_SIZE_T/2); size_t increment = i == 0 ? half + 1 : half; st_numtable_increment(frame_data->lines, (st_data_t)line, increment); } prev_frame = frame; } }