Skip to content

Commit b2d87f4

Browse files
committed
Maybe we remove custom exception classes
1 parent 7a99d1e commit b2d87f4

31 files changed

+193
-251
lines changed

ext/datadog_profiling_native_extension/clock_id_from_pthread.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void self_test_clock_id(void) {
1919
rb_nativethread_id_t expected_pthread_id = pthread_self();
2020
rb_nativethread_id_t actual_pthread_id = pthread_id_for(rb_thread_current());
2121

22-
if (expected_pthread_id != actual_pthread_id) raise_error(eDatadogRuntimeError, "pthread_id_for() self-test failed");
22+
if (expected_pthread_id != actual_pthread_id) raise_error(rb_eRuntimeError, "pthread_id_for() self-test failed");
2323
}
2424

2525
// Safety: This function is assumed never to raise exceptions by callers

ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ void collectors_cpu_and_wall_time_worker_init(VALUE profiling_module) {
289289
after_gc_from_postponed_job_handle == POSTPONED_JOB_HANDLE_INVALID ||
290290
after_gvl_running_from_postponed_job_handle == POSTPONED_JOB_HANDLE_INVALID
291291
) {
292-
raise_error(eDatadogRuntimeError, "Failed to register profiler postponed jobs (got POSTPONED_JOB_HANDLE_INVALID)");
292+
raise_error(rb_eRuntimeError, "Failed to register profiler postponed jobs (got POSTPONED_JOB_HANDLE_INVALID)");
293293
}
294294
#else
295295
gc_finalize_deferred_workaround = objspace_ptr_for_gc_finalize_deferred_workaround();
@@ -472,7 +472,7 @@ static VALUE _native_sampling_loop(DDTRACE_UNUSED VALUE _self, VALUE instance) {
472472
cpu_and_wall_time_worker_state *old_state = active_sampler_instance_state;
473473
if (old_state != NULL) {
474474
if (is_thread_alive(old_state->owner_thread)) {
475-
raise_error(eDatadogRuntimeError, "Could not start CpuAndWallTimeWorker: There's already another instance of CpuAndWallTimeWorker active in a different thread");
475+
raise_error(rb_eRuntimeError, "Could not start CpuAndWallTimeWorker: There's already another instance of CpuAndWallTimeWorker active in a different thread");
476476
} else {
477477
// The previously active thread seems to have died without cleaning up after itself.
478478
// In this case, we can still go ahead and start the profiler BUT we make sure to disable any existing tracepoint
@@ -818,7 +818,7 @@ static VALUE release_gvl_and_run_sampling_trigger_loop(VALUE instance) {
818818
NULL
819819
);
820820
#else
821-
raise_error(eDatadogArgumentError, "GVL profiling is not supported in this Ruby version");
821+
raise_error(rb_eArgError, "GVL profiling is not supported in this Ruby version");
822822
#endif
823823
}
824824

@@ -1090,7 +1090,7 @@ static void reset_stats_not_thread_safe(cpu_and_wall_time_worker_state *state) {
10901090
static void sleep_for(uint64_t time_ns) {
10911091
// As a simplification, we currently only support setting .tv_nsec
10921092
if (time_ns >= SECONDS_AS_NS(1)) {
1093-
grab_gvl_and_raise(eDatadogArgumentError, "sleep_for can only sleep for less than 1 second, time_ns: %"PRIu64, time_ns);
1093+
grab_gvl_and_raise(rb_eArgError, "sleep_for can only sleep for less than 1 second, time_ns: %"PRIu64, time_ns);
10941094
}
10951095

10961096
struct timespec time_to_sleep = {.tv_nsec = time_ns};
@@ -1281,7 +1281,7 @@ static VALUE rescued_sample_allocation(DDTRACE_UNUSED VALUE unused) {
12811281

12821282
static void delayed_error(cpu_and_wall_time_worker_state *state, const char *error) {
12831283
// If we can't raise an immediate exception at the calling site, use the asynchronous flow through the main worker loop.
1284-
stop_state(state, rb_exc_new_cstr(eDatadogRuntimeError, error));
1284+
stop_state(state, rb_exc_new_cstr(rb_eRuntimeError, error));
12851285
}
12861286

12871287
static VALUE _native_delayed_error(DDTRACE_UNUSED VALUE self, VALUE instance, VALUE error_msg) {

ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void discrete_dynamic_sampler_reset(discrete_dynamic_sampler *sampler, long now_
5151

5252
void discrete_dynamic_sampler_set_overhead_target_percentage(discrete_dynamic_sampler *sampler, double target_overhead, long now_ns) {
5353
if (target_overhead <= 0 || target_overhead > 100) {
54-
raise_error(eDatadogArgumentError, "Target overhead must be a double between ]0,100] was %f", target_overhead);
54+
raise_error(rb_eArgError, "Target overhead must be a double between ]0,100] was %f", target_overhead);
5555
}
5656
sampler->target_overhead = target_overhead;
5757
return discrete_dynamic_sampler_reset(sampler, now_ns);
@@ -369,7 +369,7 @@ static VALUE _native_new(VALUE klass) {
369369

370370
long now_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE);
371371
if (now_ns == 0) {
372-
raise_error(eDatadogRuntimeError, "failed to get clock time");
372+
raise_error(rb_eRuntimeError, "failed to get clock time");
373373
}
374374
discrete_dynamic_sampler_init(&state->sampler, "test sampler", now_ns);
375375

ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ uint8_t gc_profiling_set_metadata(ddog_prof_Label *labels, int labels_length) {
7272
1; // gc type
7373

7474
if (max_label_count > labels_length) {
75-
raise_error(eDatadogArgumentError, "BUG: gc_profiling_set_metadata invalid labels_length (%d) < max_label_count (%d)", labels_length, max_label_count);
75+
raise_error(rb_eArgError, "BUG: gc_profiling_set_metadata invalid labels_length (%d) < max_label_count (%d)", labels_length, max_label_count);
7676
}
7777

7878
uint8_t label_pos = 0;
@@ -120,7 +120,7 @@ uint8_t gc_profiling_set_metadata(ddog_prof_Label *labels, int labels_length) {
120120
};
121121

122122
if (label_pos > max_label_count) {
123-
raise_error(eDatadogRuntimeError, "BUG: gc_profiling_set_metadata unexpected label_pos (%d) > max_label_count (%d)", label_pos, max_label_count);
123+
raise_error(rb_eRuntimeError, "BUG: gc_profiling_set_metadata unexpected label_pos (%d) > max_label_count (%d)", label_pos, max_label_count);
124124
}
125125

126126
return label_pos;

ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ static void *run_idle_sampling_loop(void *state_ptr) {
153153
// Process pending action
154154
if (next_action == ACTION_RUN) {
155155
if (run_action_function == NULL) {
156-
grab_gvl_and_raise(eDatadogRuntimeError, "Unexpected NULL run_action_function in run_idle_sampling_loop");
156+
grab_gvl_and_raise(rb_eRuntimeError, "Unexpected NULL run_action_function in run_idle_sampling_loop");
157157
}
158158

159159
run_action_function();
@@ -206,7 +206,7 @@ static VALUE _native_stop(DDTRACE_UNUSED VALUE self, VALUE self_instance) {
206206
void idle_sampling_helper_request_action(VALUE self_instance, void (*run_action_function)(void)) {
207207
idle_sampling_loop_state *state;
208208
if (!rb_typeddata_is_kind_of(self_instance, &idle_sampling_helper_typed_data)) {
209-
grab_gvl_and_raise(eDatadogTypeError, "Wrong argument for idle_sampling_helper_request_action");
209+
grab_gvl_and_raise(rb_eTypeError, "Wrong argument for idle_sampling_helper_request_action");
210210
}
211211
// This should never fail the the above check passes
212212
TypedData_Get_Struct(self_instance, idle_sampling_loop_state, &idle_sampling_helper_typed_data, state);

ext/datadog_profiling_native_extension/collectors_stack.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,11 @@ void sample_thread(
285285
// here, but >= 0 makes this easier to understand/debug.
286286
bool only_wall_time = cpu_or_wall_sample && values.cpu_time_ns == 0 && values.wall_time_ns >= 0;
287287

288-
if (cpu_or_wall_sample && state_label == NULL) raise_error(eDatadogRuntimeError, "BUG: Unexpected missing state_label");
288+
if (cpu_or_wall_sample && state_label == NULL) raise_error(rb_eRuntimeError, "BUG: Unexpected missing state_label");
289289

290290
if (has_cpu_time) {
291291
state_label->str = DDOG_CHARSLICE_C("had cpu");
292-
if (labels.is_gvl_waiting_state) raise_error(eDatadogRuntimeError, "BUG: Unexpected combination of cpu-time with is_gvl_waiting");
292+
if (labels.is_gvl_waiting_state) raise_error(rb_eRuntimeError, "BUG: Unexpected combination of cpu-time with is_gvl_waiting");
293293
}
294294

295295
int top_of_stack_position = captured_frames - 1;
@@ -601,8 +601,8 @@ bool prepare_sample_thread(VALUE thread, sampling_buffer *buffer) {
601601
}
602602

603603
uint16_t sampling_buffer_check_max_frames(int max_frames) {
604-
if (max_frames < 5) raise_error(eDatadogArgumentError, "Invalid max_frames: value must be >= 5");
605-
if (max_frames > MAX_FRAMES_LIMIT) raise_error(eDatadogArgumentError, "Invalid max_frames: value must be <= " MAX_FRAMES_LIMIT_AS_STRING);
604+
if (max_frames < 5) raise_error(rb_eArgError, "Invalid max_frames: value must be >= 5");
605+
if (max_frames > MAX_FRAMES_LIMIT) raise_error(rb_eArgError, "Invalid max_frames: value must be <= " MAX_FRAMES_LIMIT_AS_STRING);
606606
return max_frames;
607607
}
608608

@@ -619,7 +619,7 @@ void sampling_buffer_initialize(sampling_buffer *buffer, uint16_t max_frames, dd
619619

620620
void sampling_buffer_free(sampling_buffer *buffer) {
621621
if (buffer->max_frames == 0 || buffer->locations == NULL || buffer->stack_buffer == NULL) {
622-
raise_error(eDatadogArgumentError, "sampling_buffer_free called with invalid buffer");
622+
raise_error(rb_eArgError, "sampling_buffer_free called with invalid buffer");
623623
}
624624

625625
ruby_xfree(buffer->stack_buffer);

ext/datadog_profiling_native_extension/collectors_thread_context.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _sel
519519
} else if (otel_context_enabled == ID2SYM(rb_intern("both"))) {
520520
state->otel_context_enabled = OTEL_CONTEXT_ENABLED_BOTH;
521521
} else {
522-
raise_error(eDatadogArgumentError, "Unexpected value for otel_context_enabled: %+" PRIsVALUE, otel_context_enabled);
522+
raise_error(rb_eArgError, "Unexpected value for otel_context_enabled: %+" PRIsVALUE, otel_context_enabled);
523523
}
524524

525525
global_waiting_for_gvl_threshold_ns = NUM2UINT(waiting_for_gvl_threshold_ns);
@@ -540,7 +540,7 @@ static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _sel
540540
static VALUE _native_sample(DDTRACE_UNUSED VALUE _self, VALUE collector_instance, VALUE profiler_overhead_stack_thread, VALUE allow_exception) {
541541
ENFORCE_BOOLEAN(allow_exception);
542542

543-
if (!is_thread_alive(profiler_overhead_stack_thread)) raise_error(eDatadogArgumentError, "Unexpected: profiler_overhead_stack_thread is not alive");
543+
if (!is_thread_alive(profiler_overhead_stack_thread)) raise_error(rb_eArgError, "Unexpected: profiler_overhead_stack_thread is not alive");
544544

545545
if (allow_exception == Qfalse) debug_enter_unsafe_context();
546546

@@ -832,7 +832,7 @@ VALUE thread_context_collector_sample_after_gc(VALUE self_instance) {
832832
TypedData_Get_Struct(self_instance, thread_context_collector_state, &thread_context_collector_typed_data, state);
833833

834834
if (state->gc_tracking.wall_time_at_previous_gc_ns == INVALID_TIME) {
835-
raise_error(eDatadogRuntimeError, "BUG: Unexpected call to sample_after_gc without valid GC information available");
835+
raise_error(rb_eRuntimeError, "BUG: Unexpected call to sample_after_gc without valid GC information available");
836836
}
837837

838838
int max_labels_needed_for_gc = 7; // Magic number gets validated inside gc_profiling_set_metadata
@@ -999,7 +999,7 @@ static void trigger_sample_for_thread(
999999
// @ivoanjo: I wonder if C compilers are smart enough to statically prove this check never triggers unless someone
10001000
// changes the code erroneously and remove it entirely?
10011001
if (label_pos > max_label_count) {
1002-
raise_error(eDatadogRuntimeError, "BUG: Unexpected label_pos (%d) > max_label_count (%d)", label_pos, max_label_count);
1002+
raise_error(rb_eRuntimeError, "BUG: Unexpected label_pos (%d) > max_label_count (%d)", label_pos, max_label_count);
10031003
}
10041004

10051005
ddog_prof_Slice_Label slice_labels = {.ptr = labels, .len = label_pos};
@@ -1296,7 +1296,7 @@ static long update_time_since_previous_sample(long *time_at_previous_sample_ns,
12961296
elapsed_time_ns = 0;
12971297
} else {
12981298
// We don't expect non-wall time to go backwards, so let's flag this as a bug
1299-
raise_error(eDatadogRuntimeError, "BUG: Unexpected negative elapsed_time_ns between samples");
1299+
raise_error(rb_eRuntimeError, "BUG: Unexpected negative elapsed_time_ns between samples");
13001300
}
13011301
}
13021302

@@ -1962,7 +1962,7 @@ static uint64_t otel_span_id_to_uint(VALUE otel_span_id) {
19621962
thread_context_collector_state *state;
19631963
TypedData_Get_Struct(self_instance, thread_context_collector_state, &thread_context_collector_typed_data, state);
19641964

1965-
if (!state->timeline_enabled) raise_error(eDatadogRuntimeError, "GVL profiling requires timeline to be enabled");
1965+
if (!state->timeline_enabled) raise_error(rb_eRuntimeError, "GVL profiling requires timeline to be enabled");
19661966

19671967
intptr_t gvl_waiting_at = gvl_profiling_state_thread_object_get(current_thread);
19681968

@@ -2158,7 +2158,7 @@ static uint64_t otel_span_id_to_uint(VALUE otel_span_id) {
21582158
TypedData_Get_Struct(collector_instance, thread_context_collector_state, &thread_context_collector_typed_data, state);
21592159

21602160
per_thread_context *thread_context = get_context_for(thread, state);
2161-
if (thread_context == NULL) raise_error(eDatadogArgumentError, "Unexpected: This method cannot be used unless the per-thread context for the thread already exists");
2161+
if (thread_context == NULL) raise_error(rb_eArgError, "Unexpected: This method cannot be used unless the per-thread context for the thread already exists");
21622162

21632163
thread_context->cpu_time_at_previous_sample_ns += NUM2LONG(delta_ns);
21642164

ext/datadog_profiling_native_extension/datadog_ruby_common.c

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33

44
// IMPORTANT: Currently this file is copy-pasted between extensions. Make sure to update all versions when doing any change!
55

6-
// Exception classes defined in Ruby, in the `Datadog::Core` namespace.
7-
VALUE eDatadogRuntimeError = Qnil;
8-
VALUE eDatadogArgumentError = Qnil;
9-
VALUE eDatadogTypeError = Qnil;
6+
// Native extensions now use Ruby's built-in exception classes directly.
107

118
void raise_unexpected_type(VALUE value, const char *value_name, const char *type_name, const char *file, int line, const char *function_name) {
129
rb_exc_raise(
@@ -94,21 +91,15 @@ ddog_Vec_Tag convert_tags(VALUE tags_as_array) {
9491
}
9592

9693
void datadog_ruby_common_init(VALUE datadog_module) {
97-
VALUE core_module = rb_const_get(datadog_module, rb_intern("Core"));
94+
ENFORCE_TYPE(datadog_module, T_MODULE);
95+
96+
ID core_id = rb_intern("Core");
97+
VALUE core_module =
98+
rb_const_defined(datadog_module, core_id) ? rb_const_get(datadog_module, core_id) : rb_define_module_under(datadog_module, "Core");
9899
ENFORCE_TYPE(core_module, T_MODULE);
99100

100-
VALUE native_module = rb_const_get(core_module, rb_intern("Native"));
101+
ID native_id = rb_intern("Native");
102+
VALUE native_module =
103+
rb_const_defined(core_module, native_id) ? rb_const_get(core_module, native_id) : rb_define_module_under(core_module, "Native");
101104
ENFORCE_TYPE(native_module, T_MODULE);
102-
103-
rb_global_variable(&eDatadogRuntimeError);
104-
eDatadogRuntimeError = rb_const_get(native_module, rb_intern("RuntimeError"));
105-
ENFORCE_TYPE(eDatadogRuntimeError, T_CLASS);
106-
107-
rb_global_variable(&eDatadogArgumentError);
108-
eDatadogArgumentError = rb_const_get(native_module, rb_intern("ArgumentError"));
109-
ENFORCE_TYPE(eDatadogArgumentError, T_CLASS);
110-
111-
rb_global_variable(&eDatadogTypeError);
112-
eDatadogTypeError = rb_const_get(native_module, rb_intern("TypeError"));
113-
ENFORCE_TYPE(eDatadogTypeError, T_CLASS);
114105
}

ext/datadog_profiling_native_extension/datadog_ruby_common.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,7 @@ NORETURN(void raise_unexpected_type(VALUE value, const char *value_name, const c
3838
// Helper to raise errors with formatted messages
3939
NORETURN(void raise_error(VALUE error_class, const char *fmt, ...)) __attribute__ ((format (gnu_printf, 2, 3)));
4040

41-
// Exception classes defined in Ruby, in the `Datadog::Core` namespace.
42-
extern VALUE eDatadogRuntimeError;
43-
extern VALUE eDatadogArgumentError;
44-
extern VALUE eDatadogTypeError;
41+
4542

4643
// Helper to retrieve Datadog::VERSION::STRING
4744
VALUE datadog_gem_version(void);

ext/datadog_profiling_native_extension/encoded_profile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ VALUE from_ddog_prof_EncodedProfile(ddog_prof_EncodedProfile profile) {
4242
static ddog_ByteSlice get_bytes(ddog_prof_EncodedProfile *state) {
4343
ddog_prof_Result_ByteSlice raw_bytes = ddog_prof_EncodedProfile_bytes(state);
4444
if (raw_bytes.tag == DDOG_PROF_RESULT_BYTE_SLICE_ERR_BYTE_SLICE) {
45-
raise_error(eDatadogRuntimeError, "Failed to get bytes from profile: %"PRIsVALUE, get_error_details_and_drop(&raw_bytes.err));
45+
raise_error(rb_eRuntimeError, "Failed to get bytes from profile: %"PRIsVALUE, get_error_details_and_drop(&raw_bytes.err));
4646
}
4747
return raw_bytes.ok;
4848
}

0 commit comments

Comments
 (0)