datadog 2.7.1 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +69 -1
  3. data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +64 -54
  5. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
  6. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
  7. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
  8. data/ext/datadog_profiling_native_extension/collectors_stack.c +7 -7
  9. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +259 -132
  10. data/ext/datadog_profiling_native_extension/extconf.rb +0 -8
  11. data/ext/datadog_profiling_native_extension/heap_recorder.c +11 -89
  12. data/ext/datadog_profiling_native_extension/heap_recorder.h +1 -1
  13. data/ext/datadog_profiling_native_extension/http_transport.c +4 -4
  14. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +4 -1
  15. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +3 -1
  16. data/ext/datadog_profiling_native_extension/profiling.c +10 -8
  17. data/ext/datadog_profiling_native_extension/ruby_helpers.c +8 -8
  18. data/ext/datadog_profiling_native_extension/stack_recorder.c +54 -88
  19. data/ext/datadog_profiling_native_extension/stack_recorder.h +1 -1
  20. data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
  21. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
  22. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
  23. data/ext/libdatadog_api/crashtracker.c +3 -0
  24. data/ext/libdatadog_extconf_helpers.rb +1 -1
  25. data/lib/datadog/appsec/assets/waf_rules/recommended.json +355 -157
  26. data/lib/datadog/appsec/assets/waf_rules/strict.json +62 -32
  27. data/lib/datadog/appsec/component.rb +1 -8
  28. data/lib/datadog/appsec/context.rb +54 -0
  29. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +73 -0
  30. data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
  31. data/lib/datadog/appsec/contrib/active_record/patcher.rb +53 -0
  32. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +6 -6
  33. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +4 -4
  34. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +19 -28
  35. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +5 -5
  36. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
  37. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +64 -96
  38. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +10 -10
  39. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +5 -5
  40. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +6 -6
  41. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
  42. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +43 -49
  43. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +21 -32
  44. data/lib/datadog/appsec/contrib/rails/patcher.rb +1 -1
  45. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +6 -6
  46. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +41 -63
  47. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +2 -2
  48. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +5 -5
  49. data/lib/datadog/appsec/event.rb +6 -6
  50. data/lib/datadog/appsec/ext.rb +3 -1
  51. data/lib/datadog/appsec/monitor/gateway/watcher.rb +22 -32
  52. data/lib/datadog/appsec/monitor/reactive/set_user.rb +5 -5
  53. data/lib/datadog/appsec/processor/context.rb +2 -2
  54. data/lib/datadog/appsec/processor/rule_loader.rb +0 -3
  55. data/lib/datadog/appsec/remote.rb +1 -3
  56. data/lib/datadog/appsec/response.rb +7 -11
  57. data/lib/datadog/appsec.rb +6 -5
  58. data/lib/datadog/auto_instrument.rb +3 -0
  59. data/lib/datadog/core/configuration/agent_settings_resolver.rb +39 -11
  60. data/lib/datadog/core/configuration/components.rb +20 -2
  61. data/lib/datadog/core/configuration/settings.rb +10 -0
  62. data/lib/datadog/core/configuration.rb +10 -2
  63. data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
  64. data/lib/datadog/core/crashtracking/component.rb +1 -3
  65. data/lib/datadog/core/remote/client/capabilities.rb +6 -0
  66. data/lib/datadog/core/remote/client.rb +65 -59
  67. data/lib/datadog/core/telemetry/component.rb +9 -3
  68. data/lib/datadog/core/telemetry/event.rb +87 -3
  69. data/lib/datadog/core/telemetry/ext.rb +1 -0
  70. data/lib/datadog/core/telemetry/logging.rb +2 -2
  71. data/lib/datadog/core/telemetry/metric.rb +22 -0
  72. data/lib/datadog/core/telemetry/worker.rb +33 -0
  73. data/lib/datadog/di/base.rb +115 -0
  74. data/lib/datadog/di/code_tracker.rb +11 -7
  75. data/lib/datadog/di/component.rb +21 -11
  76. data/lib/datadog/di/configuration/settings.rb +11 -1
  77. data/lib/datadog/di/contrib/active_record.rb +1 -0
  78. data/lib/datadog/di/contrib/railtie.rb +15 -0
  79. data/lib/datadog/di/contrib.rb +26 -0
  80. data/lib/datadog/di/error.rb +5 -0
  81. data/lib/datadog/di/instrumenter.rb +111 -20
  82. data/lib/datadog/di/preload.rb +18 -0
  83. data/lib/datadog/di/probe.rb +11 -1
  84. data/lib/datadog/di/probe_builder.rb +1 -0
  85. data/lib/datadog/di/probe_manager.rb +8 -5
  86. data/lib/datadog/di/probe_notification_builder.rb +27 -7
  87. data/lib/datadog/di/probe_notifier_worker.rb +5 -6
  88. data/lib/datadog/di/remote.rb +124 -0
  89. data/lib/datadog/di/serializer.rb +14 -7
  90. data/lib/datadog/di/transport.rb +3 -5
  91. data/lib/datadog/di/utils.rb +7 -0
  92. data/lib/datadog/di.rb +23 -62
  93. data/lib/datadog/kit/appsec/events.rb +3 -3
  94. data/lib/datadog/kit/identity.rb +4 -4
  95. data/lib/datadog/profiling/component.rb +59 -69
  96. data/lib/datadog/profiling/http_transport.rb +1 -26
  97. data/lib/datadog/tracing/configuration/settings.rb +4 -8
  98. data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
  99. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
  100. data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
  101. data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
  102. data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
  103. data/lib/datadog/tracing/contrib/active_record/integration.rb +6 -2
  104. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +3 -1
  105. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +3 -1
  106. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +16 -4
  107. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
  108. data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
  109. data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
  110. data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
  111. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
  112. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
  113. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
  114. data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
  115. data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
  116. data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
  117. data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
  118. data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
  119. data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
  120. data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
  121. data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
  122. data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
  123. data/lib/datadog/tracing/span.rb +12 -4
  124. data/lib/datadog/tracing/span_event.rb +123 -3
  125. data/lib/datadog/tracing/span_operation.rb +6 -0
  126. data/lib/datadog/tracing/transport/serializable_trace.rb +24 -6
  127. data/lib/datadog/version.rb +2 -2
  128. data/lib/datadog.rb +3 -0
  129. metadata +30 -17
  130. data/lib/datadog/appsec/processor/actions.rb +0 -49
  131. data/lib/datadog/appsec/reactive/operation.rb +0 -68
  132. data/lib/datadog/appsec/scope.rb +0 -58
  133. data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
@@ -170,11 +170,6 @@ $defs << "-DNO_THREAD_TID" if RUBY_VERSION < "3.1"
170
170
  # On older Rubies, there was no jit_return member on the rb_control_frame_t struct
171
171
  $defs << "-DNO_JIT_RETURN" if RUBY_VERSION < "3.1"
172
172
 
173
- # On older Rubies, rb_gc_force_recycle allowed to free objects in a way that
174
- # would be invisible to free tracepoints, finalizers and without cleaning
175
- # obj_to_id_tbl mappings.
176
- $defs << "-DHAVE_WORKING_RB_GC_FORCE_RECYCLE" if RUBY_VERSION < "3.1"
177
-
178
173
  # On older Rubies, there are no Ractors
179
174
  $defs << "-DNO_RACTORS" if RUBY_VERSION < "3"
180
175
 
@@ -184,9 +179,6 @@ $defs << "-DNO_IMEMO_NAME" if RUBY_VERSION < "3"
184
179
  # On older Rubies, objects would not move
185
180
  $defs << "-DNO_T_MOVED" if RUBY_VERSION < "2.7"
186
181
 
187
- # On older Rubies, there was no RUBY_SEEN_OBJ_ID flag
188
- $defs << "-DNO_SEEN_OBJ_ID_FLAG" if RUBY_VERSION < "2.7"
189
-
190
182
  # On older Rubies, rb_global_vm_lock_struct did not include the owner field
191
183
  $defs << "-DNO_GVL_OWNER" if RUBY_VERSION < "2.6"
192
184
 
@@ -7,10 +7,6 @@
7
7
  #include "libdatadog_helpers.h"
8
8
  #include "time_helpers.h"
9
9
 
10
- #if (defined(HAVE_WORKING_RB_GC_FORCE_RECYCLE) && ! defined(NO_SEEN_OBJ_ID_FLAG))
11
- #define CAN_APPLY_GC_FORCE_RECYCLE_BUG_WORKAROUND
12
- #endif
13
-
14
10
  // Minimum age (in GC generations) of heap objects we want to include in heap
15
11
  // recorder iterations. Object with age 0 represent objects that have yet to undergo
16
12
  // a GC and, thus, may just be noise/trash at instant of iteration and are usually not
@@ -123,9 +119,6 @@ typedef struct {
123
119
  // Pointer to the (potentially partial) object_record containing metadata about an ongoing recording.
124
120
  // When NULL, this symbolizes an unstarted/invalid recording.
125
121
  object_record *object_record;
126
- // A flag to track whether we had to force set the RUBY_FL_SEEN_OBJ_ID flag on this object
127
- // as part of our workaround around rb_gc_force_recycle issues.
128
- bool did_recycle_workaround;
129
122
  } recording;
130
123
 
131
124
  struct heap_recorder {
@@ -342,46 +335,12 @@ void start_heap_allocation_recording(heap_recorder *heap_recorder, VALUE new_obj
342
335
  rb_raise(rb_eRuntimeError, "Detected a bignum object id. These are not supported by heap profiling.");
343
336
  }
344
337
 
345
- bool did_recycle_workaround = false;
346
-
347
- #ifdef CAN_APPLY_GC_FORCE_RECYCLE_BUG_WORKAROUND
348
- // If we are in a ruby version that has a working rb_gc_force_recycle implementation,
349
- // its usage may lead to an object being re-used outside of the typical GC cycle.
350
- //
351
- // This re-use is in theory invisible to us unless we're lucky enough to sample both
352
- // the original object and the replacement that uses the recycled slot.
353
- //
354
- // In practice, we've observed (https://github.com/DataDog/dd-trace-rb/pull/3366)
355
- // that non-noop implementations of rb_gc_force_recycle have an implementation bug
356
- // which results in the object that re-used the recycled slot inheriting the same
357
- // object id without setting the FL_SEEN_OBJ_ID flag. We rely on this knowledge to
358
- // "observe" implicit frees when an object we are tracking is force-recycled.
359
- //
360
- // However, it may happen that we start tracking a new object and that object was
361
- // allocated on a recycled slot. Due to the bug, this object would be missing the
362
- // FL_SEEN_OBJ_ID flag even though it was not recycled itself. If we left it be,
363
- // when we're doing our liveness check, the absence of the flag would trigger our
364
- // implicit free workaround and the object would be inferred as recycled even though
365
- // it might still be alive.
366
- //
367
- // Thus, if we detect that this new allocation is already missing the flag at the start
368
- // of the heap allocation recording, we force-set it. This should be safe since we
369
- // just called rb_obj_id on it above and the expectation is that any flaggable object
370
- // that goes through it ends up with the flag set (as evidenced by the GC_ASSERT
371
- // lines in https://github.com/ruby/ruby/blob/4a8d7246d15b2054eacb20f8ab3d29d39a3e7856/gc.c#L4050C14-L4050C14).
372
- if (RB_FL_ABLE(new_obj) && !RB_FL_TEST(new_obj, RUBY_FL_SEEN_OBJ_ID)) {
373
- RB_FL_SET(new_obj, RUBY_FL_SEEN_OBJ_ID);
374
- did_recycle_workaround = true;
375
- }
376
- #endif
377
-
378
338
  heap_recorder->active_recording = (recording) {
379
339
  .object_record = object_record_new(FIX2LONG(ruby_obj_id), NULL, (live_object_data) {
380
340
  .weight = weight * heap_recorder->sample_rate,
381
341
  .class = alloc_class != NULL ? string_from_char_slice(*alloc_class) : NULL,
382
342
  .alloc_gen = rb_gc_count(),
383
- }),
384
- .did_recycle_workaround = did_recycle_workaround,
343
+ }),
385
344
  };
386
345
  }
387
346
 
@@ -685,41 +644,6 @@ static int st_object_record_update(st_data_t key, st_data_t value, st_data_t ext
685
644
 
686
645
  // If we got this far, then we found a valid live object for the tracked id.
687
646
 
688
- #ifdef CAN_APPLY_GC_FORCE_RECYCLE_BUG_WORKAROUND
689
- // If we are in a ruby version that has a working rb_gc_force_recycle implementation,
690
- // its usage may lead to an object being re-used outside of the typical GC cycle.
691
- //
692
- // This re-use is in theory invisible to us and would mean that the ref from which we
693
- // collected the object_record metadata may not be the same as the current ref and
694
- // thus any further reporting would be innacurately attributed to stale metadata.
695
- //
696
- // In practice, there is a way for us to notice that this happened because of a bug
697
- // in the implementation of rb_gc_force_recycle. Our heap profiler relies on object
698
- // ids and id2ref to detect whether objects are still alive. Turns out that when an
699
- // object with an id is re-used via rb_gc_force_recycle, it will "inherit" the ID
700
- // of the old object but it will NOT have the FL_SEEN_OBJ_ID as per the experiment
701
- // in https://github.com/DataDog/dd-trace-rb/pull/3360#discussion_r1442823517
702
- //
703
- // Thus, if we detect that the ref we just resolved above is missing this flag, we can
704
- // safely say re-use happened and thus treat it as an implicit free of the object
705
- // we were tracking (the original one which got recycled).
706
- if (RB_FL_ABLE(ref) && !RB_FL_TEST(ref, RUBY_FL_SEEN_OBJ_ID)) {
707
-
708
- // NOTE: We don't really need to set this flag for heap recorder to work correctly
709
- // but doing so partially mitigates a bug in runtimes with working rb_gc_force_recycle
710
- // which leads to broken invariants and leaking of entries in obj_to_id and id_to_obj
711
- // tables in objspace. We already do the same thing when we sample a recycled object,
712
- // here we apply it as well to objects that replace recycled objects that were being
713
- // tracked. More details in https://github.com/DataDog/dd-trace-rb/pull/3366
714
- RB_FL_SET(ref, RUBY_FL_SEEN_OBJ_ID);
715
-
716
- on_committed_object_record_cleanup(recorder, record);
717
- recorder->stats_last_update.objects_dead++;
718
- return ST_DELETE;
719
- }
720
-
721
- #endif
722
-
723
647
  if (
724
648
  recorder->size_enabled &&
725
649
  recorder->update_include_old && // We only update sizes when doing a full update
@@ -732,6 +656,10 @@ static int st_object_record_update(st_data_t key, st_data_t value, st_data_t ext
732
656
  record->object_data.is_frozen = RB_OBJ_FROZEN(ref);
733
657
  }
734
658
 
659
+ // Ensure that ref is kept on the stack so the Ruby garbage collector does not try to clean up the object before this
660
+ // point.
661
+ RB_GC_GUARD(ref);
662
+
735
663
  recorder->stats_last_update.objects_alive++;
736
664
  if (record->object_data.is_frozen) {
737
665
  recorder->stats_last_update.objects_frozen++;
@@ -803,18 +731,12 @@ static int update_object_record_entry(DDTRACE_UNUSED st_data_t *key, st_data_t *
803
731
  object_record *new_object_record = recording.object_record;
804
732
  if (existing) {
805
733
  object_record *existing_record = (object_record*) (*value);
806
- if (recording.did_recycle_workaround) {
807
- // In this case, it's possible for an object id to be re-used and we were lucky enough to have
808
- // sampled both the original object and the replacement so cleanup the old one and replace it with
809
- // the new object_record (i.e. treat this as a combined free+allocation).
810
- on_committed_object_record_cleanup(update_data->heap_recorder, existing_record);
811
- } else {
812
- // This is not supposed to happen, raising...
813
- VALUE existing_inspect = object_record_inspect(existing_record);
814
- VALUE new_inspect = object_record_inspect(new_object_record);
815
- rb_raise(rb_eRuntimeError, "Object ids are supposed to be unique. We got 2 allocation recordings with "
816
- "the same id. previous=%"PRIsVALUE" new=%"PRIsVALUE, existing_inspect, new_inspect);
817
- }
734
+
735
+ // This is not supposed to happen, raising...
736
+ VALUE existing_inspect = object_record_inspect(existing_record);
737
+ VALUE new_inspect = object_record_inspect(new_object_record);
738
+ rb_raise(rb_eRuntimeError, "Object ids are supposed to be unique. We got 2 allocation recordings with "
739
+ "the same id. previous=%"PRIsVALUE" new=%"PRIsVALUE, existing_inspect, new_inspect);
818
740
  }
819
741
  // Always carry on with the update, we want the new record to be there at the end
820
742
  (*value) = (st_data_t) new_object_record;
@@ -17,7 +17,7 @@
17
17
  typedef struct heap_recorder heap_recorder;
18
18
 
19
19
  // Extra data associated with each live object being tracked.
20
- typedef struct live_object_data {
20
+ typedef struct {
21
21
  // The weight of this object from a sampling perspective.
22
22
  //
23
23
  // A notion of weight is preserved for each tracked object to allow for an approximate
@@ -13,13 +13,13 @@ static VALUE error_symbol = Qnil; // :error in Ruby
13
13
 
14
14
  static VALUE library_version_string = Qnil;
15
15
 
16
- struct call_exporter_without_gvl_arguments {
16
+ typedef struct {
17
17
  ddog_prof_Exporter *exporter;
18
18
  ddog_prof_Exporter_Request_BuildResult *build_result;
19
19
  ddog_CancellationToken *cancel_token;
20
20
  ddog_prof_Exporter_SendResult result;
21
21
  bool send_ran;
22
- };
22
+ } call_exporter_without_gvl_arguments;
23
23
 
24
24
  static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string);
25
25
  static VALUE _native_validate_exporter(VALUE self, VALUE exporter_configuration);
@@ -165,7 +165,7 @@ static VALUE perform_export(
165
165
 
166
166
  // We'll release the Global VM Lock while we're calling send, so that the Ruby VM can continue to work while this
167
167
  // is pending
168
- struct call_exporter_without_gvl_arguments args =
168
+ call_exporter_without_gvl_arguments args =
169
169
  {.exporter = exporter, .build_result = &build_result, .cancel_token = cancel_token, .send_ran = false};
170
170
 
171
171
  // We use rb_thread_call_without_gvl2 instead of rb_thread_call_without_gvl as the gvl2 variant never raises any
@@ -300,7 +300,7 @@ static VALUE _native_do_export(
300
300
  }
301
301
 
302
302
  static void *call_exporter_without_gvl(void *call_args) {
303
- struct call_exporter_without_gvl_arguments *args = (struct call_exporter_without_gvl_arguments*) call_args;
303
+ call_exporter_without_gvl_arguments *args = (call_exporter_without_gvl_arguments*) call_args;
304
304
 
305
305
  args->result = ddog_prof_Exporter_send(args->exporter, &args->build_result->ok, args->cancel_token);
306
306
  args->send_ran = true;
@@ -158,7 +158,7 @@ bool is_current_thread_holding_the_gvl(void) {
158
158
  //
159
159
  // Thus an incorrect `is_current_thread_holding_the_gvl` result may lead to issues inside `rb_postponed_job_register_one`.
160
160
  //
161
- // For this reason we currently do not enable the new Ruby profiler on Ruby 2.5 by default, and we print a
161
+ // For this reason we default to use the "no signals workaround" on Ruby 2.5 by default, and we print a
162
162
  // warning when customers force-enable it.
163
163
  bool gvl_acquired = vm->gvl.acquired != 0;
164
164
  rb_thread_t *current_owner = vm->running_thread;
@@ -800,3 +800,6 @@ static inline int ddtrace_imemo_type(VALUE imemo) {
800
800
  return current_thread;
801
801
  }
802
802
  #endif
803
+
804
+ // Is the VM smack in the middle of raising an exception?
805
+ bool is_raised_flag_set(VALUE thread) { return thread_struct_from_object(thread)->ec->raised_flag > 0; }
@@ -18,7 +18,7 @@ typedef struct {
18
18
  rb_nativethread_id_t owner;
19
19
  } current_gvl_owner;
20
20
 
21
- typedef struct frame_info {
21
+ typedef struct {
22
22
  union {
23
23
  struct {
24
24
  VALUE iseq;
@@ -68,3 +68,5 @@ const char *imemo_kind(VALUE imemo);
68
68
 
69
69
  #define ENFORCE_THREAD(value) \
70
70
  { if (RB_UNLIKELY(!rb_typeddata_is_kind_of(value, RTYPEDDATA_TYPE(rb_thread_current())))) raise_unexpected_type(value, ADD_QUOTES(value), "Thread", __FILE__, __LINE__, __func__); }
71
+
72
+ bool is_raised_flag_set(VALUE thread);
@@ -11,6 +11,7 @@
11
11
  #include "ruby_helpers.h"
12
12
  #include "setup_signal_handler.h"
13
13
  #include "time_helpers.h"
14
+ #include "unsafe_api_calls_check.h"
14
15
 
15
16
  // Each class/module here is implemented in their separate file
16
17
  void collectors_cpu_and_wall_time_worker_init(VALUE profiling_module);
@@ -56,6 +57,7 @@ void DDTRACE_EXPORT Init_datadog_profiling_native_extension(void) {
56
57
  collectors_thread_context_init(profiling_module);
57
58
  http_transport_init(profiling_module);
58
59
  stack_recorder_init(profiling_module);
60
+ unsafe_api_calls_check_init();
59
61
 
60
62
  // Hosts methods used for testing the native code using RSpec
61
63
  VALUE testing_module = rb_define_module_under(native_extension_module, "Testing");
@@ -83,16 +85,16 @@ static VALUE native_working_p(DDTRACE_UNUSED VALUE _self) {
83
85
  return Qtrue;
84
86
  }
85
87
 
86
- struct trigger_grab_gvl_and_raise_arguments {
88
+ typedef struct {
87
89
  VALUE exception_class;
88
90
  char *test_message;
89
91
  int test_message_arg;
90
- };
92
+ } trigger_grab_gvl_and_raise_arguments;
91
93
 
92
94
  static VALUE _native_grab_gvl_and_raise(DDTRACE_UNUSED VALUE _self, VALUE exception_class, VALUE test_message, VALUE test_message_arg, VALUE release_gvl) {
93
95
  ENFORCE_TYPE(test_message, T_STRING);
94
96
 
95
- struct trigger_grab_gvl_and_raise_arguments args;
97
+ trigger_grab_gvl_and_raise_arguments args;
96
98
 
97
99
  args.exception_class = exception_class;
98
100
  args.test_message = StringValueCStr(test_message);
@@ -108,7 +110,7 @@ static VALUE _native_grab_gvl_and_raise(DDTRACE_UNUSED VALUE _self, VALUE except
108
110
  }
109
111
 
110
112
  static void *trigger_grab_gvl_and_raise(void *trigger_args) {
111
- struct trigger_grab_gvl_and_raise_arguments *args = (struct trigger_grab_gvl_and_raise_arguments *) trigger_args;
113
+ trigger_grab_gvl_and_raise_arguments *args = (trigger_grab_gvl_and_raise_arguments *) trigger_args;
112
114
 
113
115
  if (args->test_message_arg >= 0) {
114
116
  grab_gvl_and_raise(args->exception_class, "%s%d", args->test_message, args->test_message_arg);
@@ -119,16 +121,16 @@ static void *trigger_grab_gvl_and_raise(void *trigger_args) {
119
121
  return NULL;
120
122
  }
121
123
 
122
- struct trigger_grab_gvl_and_raise_syserr_arguments {
124
+ typedef struct {
123
125
  int syserr_errno;
124
126
  char *test_message;
125
127
  int test_message_arg;
126
- };
128
+ } trigger_grab_gvl_and_raise_syserr_arguments;
127
129
 
128
130
  static VALUE _native_grab_gvl_and_raise_syserr(DDTRACE_UNUSED VALUE _self, VALUE syserr_errno, VALUE test_message, VALUE test_message_arg, VALUE release_gvl) {
129
131
  ENFORCE_TYPE(test_message, T_STRING);
130
132
 
131
- struct trigger_grab_gvl_and_raise_syserr_arguments args;
133
+ trigger_grab_gvl_and_raise_syserr_arguments args;
132
134
 
133
135
  args.syserr_errno = NUM2INT(syserr_errno);
134
136
  args.test_message = StringValueCStr(test_message);
@@ -144,7 +146,7 @@ static VALUE _native_grab_gvl_and_raise_syserr(DDTRACE_UNUSED VALUE _self, VALUE
144
146
  }
145
147
 
146
148
  static void *trigger_grab_gvl_and_raise_syserr(void *trigger_args) {
147
- struct trigger_grab_gvl_and_raise_syserr_arguments *args = (struct trigger_grab_gvl_and_raise_syserr_arguments *) trigger_args;
149
+ trigger_grab_gvl_and_raise_syserr_arguments *args = (trigger_grab_gvl_and_raise_syserr_arguments *) trigger_args;
148
150
 
149
151
  if (args->test_message_arg >= 0) {
150
152
  grab_gvl_and_raise_syserr(args->syserr_errno, "%s%d", args->test_message, args->test_message_arg);
@@ -23,18 +23,18 @@ void ruby_helpers_init(void) {
23
23
 
24
24
  #define MAX_RAISE_MESSAGE_SIZE 256
25
25
 
26
- struct raise_arguments {
26
+ typedef struct {
27
27
  VALUE exception_class;
28
28
  char exception_message[MAX_RAISE_MESSAGE_SIZE];
29
- };
29
+ } raise_args;
30
30
 
31
31
  static void *trigger_raise(void *raise_arguments) {
32
- struct raise_arguments *args = (struct raise_arguments *) raise_arguments;
32
+ raise_args *args = (raise_args *) raise_arguments;
33
33
  rb_raise(args->exception_class, "%s", args->exception_message);
34
34
  }
35
35
 
36
36
  void grab_gvl_and_raise(VALUE exception_class, const char *format_string, ...) {
37
- struct raise_arguments args;
37
+ raise_args args;
38
38
 
39
39
  args.exception_class = exception_class;
40
40
 
@@ -55,18 +55,18 @@ void grab_gvl_and_raise(VALUE exception_class, const char *format_string, ...) {
55
55
  rb_bug("[ddtrace] Unexpected: Reached the end of grab_gvl_and_raise while raising '%s'\n", args.exception_message);
56
56
  }
57
57
 
58
- struct syserr_raise_arguments {
58
+ typedef struct {
59
59
  int syserr_errno;
60
60
  char exception_message[MAX_RAISE_MESSAGE_SIZE];
61
- };
61
+ } syserr_raise_args;
62
62
 
63
63
  static void *trigger_syserr_raise(void *syserr_raise_arguments) {
64
- struct syserr_raise_arguments *args = (struct syserr_raise_arguments *) syserr_raise_arguments;
64
+ syserr_raise_args *args = (syserr_raise_args *) syserr_raise_arguments;
65
65
  rb_syserr_fail(args->syserr_errno, args->exception_message);
66
66
  }
67
67
 
68
68
  void grab_gvl_and_raise_syserr(int syserr_errno, const char *format_string, ...) {
69
- struct syserr_raise_arguments args;
69
+ syserr_raise_args args;
70
70
 
71
71
  args.syserr_errno = syserr_errno;
72
72