Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include "libdatadog_helpers.h"

void gc_profiling_init(void);
bool gc_profiling_has_major_gc_finished(void);
uint8_t gc_profiling_set_metadata(ddog_prof_Label *labels, int labels_length);
14 changes: 7 additions & 7 deletions ext/datadog_profiling_native_extension/collectors_stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ typedef struct {
sample_values values;
sample_labels labels;
VALUE thread;
ddog_prof_Location *locations;
fixme_ddog_prof_Location *locations;
sampling_buffer *buffer;
bool native_filenames_enabled;
st_table *native_filenames_cache;
Expand Down Expand Up @@ -172,7 +172,7 @@ static VALUE _native_sample(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self) {

int max_frames_requested = sampling_buffer_check_max_frames(NUM2INT(max_frames));

ddog_prof_Location *locations = ruby_xcalloc(max_frames_requested, sizeof(ddog_prof_Location));
fixme_ddog_prof_Location *locations = ruby_xcalloc(max_frames_requested, sizeof(fixme_ddog_prof_Location));
sampling_buffer buffer;
sampling_buffer_initialize(&buffer, max_frames_requested, locations);

Expand Down Expand Up @@ -372,9 +372,9 @@ void sample_thread(

int libdatadog_stores_stacks_flipped_from_rb_profile_frames_index = top_of_stack_position - i;

buffer->locations[libdatadog_stores_stacks_flipped_from_rb_profile_frames_index] = (ddog_prof_Location) {
buffer->locations[libdatadog_stores_stacks_flipped_from_rb_profile_frames_index] = (fixme_ddog_prof_Location) {
.mapping = {.filename = DDOG_CHARSLICE_C(""), .build_id = DDOG_CHARSLICE_C(""), .build_id_id = {}},
.function = (ddog_prof_Function) {.name = name_slice, .filename = filename_slice},
.function = (fixme_ddog_prof_Function) {.name = name_slice, .filename = filename_slice},
.line = line,
};
}
Expand Down Expand Up @@ -524,7 +524,7 @@ static void maybe_trim_template_random_ids(ddog_CharSlice *name_slice, ddog_Char
static void add_truncated_frames_placeholder(sampling_buffer* buffer) {
// Important note: The strings below are static so we don't need to worry about their lifetime. If we ever want to change
// this to non-static strings, don't forget to check that lifetimes are properly respected.
buffer->locations[0] = (ddog_prof_Location) {
buffer->locations[0] = (fixme_ddog_prof_Location) {
.mapping = {.filename = DDOG_CHARSLICE_C(""), .build_id = DDOG_CHARSLICE_C(""), .build_id_id = {}},
.function = {.name = DDOG_CHARSLICE_C("Truncated Frames"), .filename = DDOG_CHARSLICE_C(""), .filename_id = {}},
.line = 0,
Expand Down Expand Up @@ -571,7 +571,7 @@ void record_placeholder_stack(
sample_labels labels,
ddog_CharSlice placeholder_stack
) {
ddog_prof_Location placeholder_location = {
fixme_ddog_prof_Location placeholder_location = {
.mapping = {.filename = DDOG_CHARSLICE_C(""), .build_id = DDOG_CHARSLICE_C(""), .build_id_id = {}},
.function = {.name = DDOG_CHARSLICE_C(""), .filename = placeholder_stack},
.line = 0,
Expand Down Expand Up @@ -601,7 +601,7 @@ uint16_t sampling_buffer_check_max_frames(int max_frames) {
return max_frames;
}

void sampling_buffer_initialize(sampling_buffer *buffer, uint16_t max_frames, ddog_prof_Location *locations) {
void sampling_buffer_initialize(sampling_buffer *buffer, uint16_t max_frames, fixme_ddog_prof_Location *locations) {
sampling_buffer_check_max_frames(max_frames);

buffer->max_frames = max_frames;
Expand Down
4 changes: 2 additions & 2 deletions ext/datadog_profiling_native_extension/collectors_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// Used as scratch space during sampling
typedef struct {
uint16_t max_frames;
ddog_prof_Location *locations;
fixme_ddog_prof_Location *locations;
frame_info *stack_buffer;
bool pending_sample;
bool is_marking; // Used to avoid recording a sample when marking
Expand All @@ -36,7 +36,7 @@ void record_placeholder_stack(
bool prepare_sample_thread(VALUE thread, sampling_buffer *buffer);

uint16_t sampling_buffer_check_max_frames(int max_frames);
void sampling_buffer_initialize(sampling_buffer *buffer, uint16_t max_frames, ddog_prof_Location *locations);
void sampling_buffer_initialize(sampling_buffer *buffer, uint16_t max_frames, fixme_ddog_prof_Location *locations);
void sampling_buffer_free(sampling_buffer *buffer);
void sampling_buffer_mark(sampling_buffer *buffer);
static inline bool sampling_buffer_needs_marking(sampling_buffer *buffer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ typedef struct {
// "Update this when modifying state struct"

// Required by Datadog::Profiling::Collectors::Stack as a scratch buffer during sampling
ddog_prof_Location *locations;
fixme_ddog_prof_Location *locations;
uint16_t max_frames;
// Hashmap <Thread Object, per_thread_context>
// Note: Be very careful when mutating this map, as it gets read e.g. in the middle of GC and signal handlers.
Expand Down Expand Up @@ -505,7 +505,7 @@ static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _sel

// Update this when modifying state struct
state->max_frames = sampling_buffer_check_max_frames(NUM2INT(max_frames));
state->locations = ruby_xcalloc(state->max_frames, sizeof(ddog_prof_Location));
state->locations = ruby_xcalloc(state->max_frames, sizeof(fixme_ddog_prof_Location));
// hash_map_per_thread_context is already initialized, nothing to do here
state->recorder_instance = enforce_recorder_instance(recorder_instance);
state->endpoint_collection_enabled = (endpoint_collection_enabled == Qtrue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,9 @@ static inline VALUE get_error_details_and_drop(ddog_Error *error) {
ddog_Error_drop(error);
return result;
}

static inline VALUE get_status_details_and_drop(ddog_prof_Status *status) {
VALUE result = rb_str_new_cstr(status->err);
ddog_prof_Status_drop(status);
return result;
}
53 changes: 31 additions & 22 deletions ext/datadog_profiling_native_extension/heap_recorder.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ struct heap_recorder {

// Reusable arrays, implementing a flyweight pattern for things like iteration
#define REUSABLE_LOCATIONS_SIZE MAX_FRAMES_LIMIT
ddog_prof_Location *reusable_locations;
fixme_ddog_prof_Location *reusable_locations;

#define REUSABLE_FRAME_DETAILS_SIZE (2 * MAX_FRAMES_LIMIT) // because it'll be used for both function names AND file names)
ddog_prof_ManagedStringId *reusable_ids;
Expand Down Expand Up @@ -203,7 +203,7 @@ heap_recorder* heap_recorder_new(ddog_prof_ManagedStringStorage string_storage)
recorder->heap_records = st_init_table(&st_hash_type_heap_record);
recorder->object_records = st_init_numtable();
recorder->object_records_snapshot = NULL;
recorder->reusable_locations = ruby_xcalloc(REUSABLE_LOCATIONS_SIZE, sizeof(ddog_prof_Location));
recorder->reusable_locations = ruby_xcalloc(REUSABLE_LOCATIONS_SIZE, sizeof(fixme_ddog_prof_Location));
recorder->reusable_ids = ruby_xcalloc(REUSABLE_FRAME_DETAILS_SIZE, sizeof(ddog_prof_ManagedStringId));
recorder->reusable_char_slices = ruby_xcalloc(REUSABLE_FRAME_DETAILS_SIZE, sizeof(ddog_CharSlice));
recorder->active_recording = NULL;
Expand Down Expand Up @@ -681,10 +681,10 @@ static int st_object_records_iterate(DDTRACE_UNUSED st_data_t key, st_data_t val
return ST_CONTINUE;
}

ddog_prof_Location *locations = recorder->reusable_locations;
fixme_ddog_prof_Location *locations = recorder->reusable_locations;
for (uint16_t i = 0; i < stack->frames_len; i++) {
const heap_frame *frame = &stack->frames[i];
locations[i] = (ddog_prof_Location) {
locations[i] = (fixme_ddog_prof_Location) {
.mapping = {.filename = DDOG_CHARSLICE_C(""), .build_id = DDOG_CHARSLICE_C(""), .build_id_id = {}},
.function = {
.name = DDOG_CHARSLICE_C(""),
Expand Down Expand Up @@ -872,7 +872,7 @@ heap_record* heap_record_new(heap_recorder *recorder, ddog_prof_Slice_Location l
ddog_CharSlice *strings = recorder->reusable_char_slices;
// Put all the char slices in the same array; we'll pull them out in the same order from the ids array
for (uint16_t i = 0; i < stack->frames_len; i++) {
const ddog_prof_Location *location = &locations.ptr[i];
const fixme_ddog_prof_Location *location = &locations.ptr[i];
strings[i] = location->function.filename;
strings[i + stack->frames_len] = location->function.name;
}
Expand All @@ -883,7 +883,7 @@ heap_record* heap_record_new(heap_recorder *recorder, ddog_prof_Slice_Location l
stack->frames[i] = (heap_frame) {
.filename = recorder->reusable_ids[i],
.name = recorder->reusable_ids[i + stack->frames_len],
// ddog_prof_Location is a int64_t. We don't expect to have to profile files with more than
// fixme_ddog_prof_Location is a int64_t. We don't expect to have to profile files with more than
// 2M lines so this cast should be fairly safe?
.line = (int32_t) locations.ptr[i].line,
};
Expand Down Expand Up @@ -931,28 +931,37 @@ st_index_t heap_record_hash_st(st_data_t key) {
static void unintern_or_raise(heap_recorder *recorder, ddog_prof_ManagedStringId id) {
if (id.value == 0) return; // Empty string, nothing to do

ddog_prof_MaybeError result = ddog_prof_ManagedStringStorage_unintern(recorder->string_storage, id);
if (result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
rb_raise(rb_eRuntimeError, "Failed to unintern id: %"PRIsVALUE, get_error_details_and_drop(&result.some));
}
// ddog_prof_MaybeError result = ddog_prof_ManagedStringStorage_unintern(recorder->string_storage, id);
// if (result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
// rb_raise(rb_eRuntimeError, "Failed to unintern id: %"PRIsVALUE, get_error_details_and_drop(&result.some));
// }
(void)recorder;
(void)id;
rb_raise(rb_eRuntimeError, "Failed to unintern id: (FIXME stubbed out)");
}

static void unintern_all_or_raise(heap_recorder *recorder, ddog_prof_Slice_ManagedStringId ids) {
ddog_prof_MaybeError result = ddog_prof_ManagedStringStorage_unintern_all(recorder->string_storage, ids);
if (result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
rb_raise(rb_eRuntimeError, "Failed to unintern_all: %"PRIsVALUE, get_error_details_and_drop(&result.some));
}
// ddog_prof_MaybeError result = ddog_prof_ManagedStringStorage_unintern_all(recorder->string_storage, ids);
// if (result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
// rb_raise(rb_eRuntimeError, "Failed to unintern_all: %"PRIsVALUE, get_error_details_and_drop(&result.some));
// }
(void)recorder;
(void)ids;
rb_raise(rb_eRuntimeError, "Failed to unintern_all: (FIXME stubbed out)");
}

static VALUE get_ruby_string_or_raise(heap_recorder *recorder, ddog_prof_ManagedStringId id) {
ddog_StringWrapperResult get_string_result = ddog_prof_ManagedStringStorage_get_string(recorder->string_storage, id);
if (get_string_result.tag == DDOG_STRING_WRAPPER_RESULT_ERR) {
rb_raise(rb_eRuntimeError, "Failed to get string: %"PRIsVALUE, get_error_details_and_drop(&get_string_result.err));
}
VALUE ruby_string = ruby_string_from_vec_u8(get_string_result.ok.message);
ddog_StringWrapper_drop((ddog_StringWrapper *) &get_string_result.ok);

return ruby_string;
// ddog_StringWrapperResult get_string_result = ddog_prof_ManagedStringStorage_get_string(recorder->string_storage, id);
// if (get_string_result.tag == DDOG_STRING_WRAPPER_RESULT_ERR) {
// rb_raise(rb_eRuntimeError, "Failed to get string: %"PRIsVALUE, get_error_details_and_drop(&get_string_result.err));
// }
// VALUE ruby_string = ruby_string_from_vec_u8(get_string_result.ok.message);
// ddog_StringWrapper_drop((ddog_StringWrapper *) &get_string_result.ok);

// return ruby_string;
(void)recorder;
(void)id;
rb_raise(rb_eRuntimeError, "Failed to get string: (FIXME stubbed out)");
}

static inline double ewma_stat(double previous, double current) {
Expand Down
2 changes: 2 additions & 0 deletions ext/datadog_profiling_native_extension/heap_recorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <datadog/profiling.h>
#include <ruby.h>

#include "libdatadog_helpers.h"

// A heap recorder keeps track of a collection of live heap objects.
//
// All allocations observed by this recorder for which a corresponding free was
Expand Down
4 changes: 2 additions & 2 deletions ext/datadog_profiling_native_extension/http_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_r
static VALUE perform_export(
ddog_prof_ProfileExporter *exporter,
ddog_prof_EncodedProfile *profile,
ddog_prof_Exporter_Slice_File files_to_compress_and_export,
ddog_prof_Slice_Exporter_File files_to_compress_and_export,
ddog_CharSlice internal_metadata,
ddog_CharSlice info
) {
Expand Down Expand Up @@ -227,7 +227,7 @@ static VALUE _native_do_export(

int to_compress_length = have_code_provenance ? 1 : 0;
ddog_prof_Exporter_File to_compress[to_compress_length];
ddog_prof_Exporter_Slice_File files_to_compress_and_export = {.ptr = to_compress, .len = to_compress_length};
ddog_prof_Slice_Exporter_File files_to_compress_and_export = {.ptr = to_compress, .len = to_compress_length};

if (have_code_provenance) {
to_compress[0] = (ddog_prof_Exporter_File) {
Expand Down
25 changes: 16 additions & 9 deletions ext/datadog_profiling_native_extension/libdatadog_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,13 @@ size_t read_ddogerr_string_and_drop(ddog_Error *error, char *string, size_t capa
ddog_prof_ManagedStringId intern_or_raise(ddog_prof_ManagedStringStorage string_storage, ddog_CharSlice string) {
if (string.len == 0) return (ddog_prof_ManagedStringId) { 0 }; // Id 0 is always an empty string, no need to ask

ddog_prof_ManagedStringStorageInternResult intern_result = ddog_prof_ManagedStringStorage_intern(string_storage, string);
if (intern_result.tag == DDOG_PROF_MANAGED_STRING_STORAGE_INTERN_RESULT_ERR) {
rb_raise(rb_eRuntimeError, "Failed to intern string: %"PRIsVALUE, get_error_details_and_drop(&intern_result.err));
}
return intern_result.ok;
// ddog_prof_ManagedStringStorageInternResult intern_result = ddog_prof_ManagedStringStorage_intern(string_storage, string);
// if (intern_result.tag == DDOG_PROF_MANAGED_STRING_STORAGE_INTERN_RESULT_ERR) {
(void)string_storage;
(void)string;
rb_raise(rb_eRuntimeError, "Failed to intern string: (FIXME stubbed out)");
// }
// return intern_result.ok;
}

void intern_all_or_raise(
Expand All @@ -77,8 +79,13 @@ void intern_all_or_raise(
ddog_prof_ManagedStringId *output_ids,
uintptr_t output_ids_size
) {
ddog_prof_MaybeError result = ddog_prof_ManagedStringStorage_intern_all(string_storage, strings, output_ids, output_ids_size);
if (result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
rb_raise(rb_eRuntimeError, "Failed to intern_all: %"PRIsVALUE, get_error_details_and_drop(&result.some));
}
// ddog_prof_MaybeError result = ddog_prof_ManagedStringStorage_intern_all(string_storage, strings, output_ids, output_ids_size);
// if (result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
// rb_raise(rb_eRuntimeError, "Failed to intern_all: %"PRIsVALUE, get_error_details_and_drop(&result.some));
// }
(void)string_storage;
(void)strings;
(void)output_ids;
(void)output_ids_size;
rb_raise(rb_eRuntimeError, "Failed to intern_all: (FIXME stubbed out)");
}
Loading
Loading