datadog 2.29.0 → 2.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -2
  3. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +21 -12
  4. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +9 -7
  5. data/ext/datadog_profiling_native_extension/extconf.rb +4 -24
  6. data/ext/datadog_profiling_native_extension/heap_recorder.c +5 -6
  7. data/ext/datadog_profiling_native_extension/http_transport.c +51 -64
  8. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +0 -13
  9. data/ext/datadog_profiling_native_extension/profiling.c +3 -1
  10. data/ext/datadog_profiling_native_extension/setup_signal_handler.c +24 -8
  11. data/ext/datadog_profiling_native_extension/setup_signal_handler.h +1 -3
  12. data/ext/datadog_profiling_native_extension/stack_recorder.c +29 -43
  13. data/ext/libdatadog_api/crashtracker_report_exception.c +34 -144
  14. data/ext/libdatadog_api/extconf.rb +4 -21
  15. data/ext/libdatadog_extconf_helpers.rb +49 -11
  16. data/lib/datadog/ai_guard/configuration/settings.rb +3 -0
  17. data/lib/datadog/appsec/contrib/active_record/patcher.rb +3 -0
  18. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -1
  19. data/lib/datadog/appsec/contrib/excon/patcher.rb +2 -0
  20. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +1 -1
  21. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +1 -1
  22. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +4 -4
  23. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  24. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +25 -2
  25. data/lib/datadog/appsec/contrib/rack/response_body.rb +36 -0
  26. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +2 -2
  27. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  28. data/lib/datadog/appsec/contrib/rest_client/patcher.rb +2 -0
  29. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +2 -2
  30. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +3 -3
  31. data/lib/datadog/appsec/event.rb +1 -17
  32. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +2 -3
  33. data/lib/datadog/appsec/instrumentation/gateway.rb +2 -2
  34. data/lib/datadog/appsec/monitor/gateway/watcher.rb +2 -2
  35. data/lib/datadog/core/configuration/option.rb +2 -1
  36. data/lib/datadog/core/configuration/options.rb +1 -1
  37. data/lib/datadog/core/configuration/settings.rb +27 -3
  38. data/lib/datadog/core/configuration/supported_configurations.rb +16 -0
  39. data/lib/datadog/core/crashtracking/component.rb +4 -12
  40. data/lib/datadog/core/process_discovery.rb +5 -0
  41. data/lib/datadog/core/runtime/metrics.rb +1 -2
  42. data/lib/datadog/core/utils/base64.rb +1 -1
  43. data/lib/datadog/core/workers/interval_loop.rb +13 -6
  44. data/lib/datadog/core/workers/queue.rb +0 -4
  45. data/lib/datadog/core/workers/runtime_metrics.rb +9 -1
  46. data/lib/datadog/data_streams/processor.rb +1 -0
  47. data/lib/datadog/di/boot.rb +1 -0
  48. data/lib/datadog/di/component.rb +16 -4
  49. data/lib/datadog/di/instrumenter.rb +10 -6
  50. data/lib/datadog/di/probe_manager.rb +79 -62
  51. data/lib/datadog/di/probe_notification_builder.rb +39 -32
  52. data/lib/datadog/di/probe_notifier_worker.rb +52 -6
  53. data/lib/datadog/di/probe_repository.rb +198 -0
  54. data/lib/datadog/di/remote.rb +5 -6
  55. data/lib/datadog/di/serializer.rb +127 -9
  56. data/lib/datadog/di/transport/http.rb +12 -3
  57. data/lib/datadog/di/transport/input.rb +46 -8
  58. data/lib/datadog/open_feature/configuration.rb +2 -0
  59. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +13 -0
  60. data/lib/datadog/profiling/component.rb +20 -0
  61. data/lib/datadog/profiling/http_transport.rb +5 -6
  62. data/lib/datadog/profiling/profiler.rb +15 -8
  63. data/lib/datadog/tracing/contrib/dalli/integration.rb +4 -1
  64. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +5 -1
  65. data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
  66. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +5 -2
  67. data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
  68. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +5 -2
  69. data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
  70. data/lib/datadog/tracing/contrib/grape/endpoint.rb +2 -2
  71. data/lib/datadog/tracing/contrib/grape/instrumentation.rb +13 -8
  72. data/lib/datadog/tracing/contrib/grape/patcher.rb +6 -1
  73. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +5 -2
  74. data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
  75. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +5 -2
  76. data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
  77. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +5 -2
  78. data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
  79. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +5 -2
  80. data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -0
  81. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +5 -1
  82. data/lib/datadog/tracing/contrib/karafka/ext.rb +1 -0
  83. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +5 -2
  84. data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
  85. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +5 -1
  86. data/lib/datadog/tracing/contrib/rack/ext.rb +1 -0
  87. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +5 -2
  88. data/lib/datadog/tracing/contrib/rails/ext.rb +1 -0
  89. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +5 -2
  90. data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
  91. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +5 -1
  92. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  93. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +5 -1
  94. data/lib/datadog/tracing/contrib/sinatra/ext.rb +1 -0
  95. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +5 -1
  96. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +1 -0
  97. data/lib/datadog/tracing/metadata/ext.rb +4 -0
  98. data/lib/datadog/tracing/sync_writer.rb +0 -1
  99. data/lib/datadog/tracing/transport/trace_formatter.rb +11 -0
  100. data/lib/datadog/tracing/writer.rb +0 -1
  101. data/lib/datadog/version.rb +1 -1
  102. metadata +8 -7
  103. data/lib/datadog/tracing/workers/trace_writer.rb +0 -204
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6f762ad624ddb0a21d753a524132de0f59e617e63f723fabc6c305949a77554d
4
- data.tar.gz: 217159cbaea1102ba47a97deb73927919d8152264701322719aad722391d75aa
3
+ metadata.gz: f2983471f43d0c9b3473b3c65d0ca656514c6cf8cd7a32e35ec26826193fe533
4
+ data.tar.gz: 687d088d90ce4ee0ae5af66d9e604135f058bd7609641f4c7963f1ba32a2bb37
5
5
  SHA512:
6
- metadata.gz: 711466d29940c6b22b5964744e7d1b6dbf5a002ca5992dbc01d61718f16cc66b33dcc7bee2604c4c2ba64a9efb8014114d015d44a109e1b5f55b1375d36c927a
7
- data.tar.gz: 1490e2ab41fdf0c7ce673bbb7eaa1ccc28073cd757576a30734ce3674bef89fd58aa2876b2e9d2e26e12119e45b1d90f787e260d86cfc6e1fa5055bf14ba16b0
6
+ metadata.gz: 96f3744eadab0292666e18beac7deab2a6b7ef61b0da216ab4490e7621b0cec7839d18a519079b5b0563e2a260388b63ef59b5243a65c3d6ba997f3c7981986c
7
+ data.tar.gz: a82f01f50d499f1a08309f23144e5453cb9cf79bdc5b0c7daa9b3c9c373e3a41983babe3f86dc027f2dd2e9f056bc4b7645a49f799531e40eae9455ab7e00a6d
data/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [2.30.0] - 2026-03-19
6
+
7
+ ### Added
8
+
9
+ * Core: Enable `libdatadog`-based features and tests on macOS ([#5351][])
10
+ * Tracing: Add `_dd.p.ksr` propagated tag to transmit Knuth sampling rate for backend resampling ([#5436][])
11
+ * Tracing: Integrations: Add `DD_TRACE_<INTEGRATION>_DISTRIBUTED_TRACING` environment variables to control distributed tracing per integration ([#5396][])
12
+ * Profiling: Add profiler setting `experimental_use_system_dns` to use system DNS resolver (defaults to true) ([#5425][], [#5449][])
13
+ * Profiling: Allow lowering CPU profiling sampling interval with `experimental_cpu_sampling_interval_ms` setting ([#5424][])
14
+
15
+ ### Changed
16
+
17
+ * Core: Enable process tags by default by setting `DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED`, expanding tag collection for Tracing, Database Monitoring, Data Streams Monitoring, Profiling, Runtime Metrics, Process Discovery, Remote Configuration, Telemetry, Dynamic Instrumentation, and CrashTracking ([#5432][])
18
+ * Core: Upgrade `libdatadog` dependency to version 29.0.0 ([#5274][], [#5461][])
19
+ * Core: Remove dependency on `pkg-config` system tool for native extension builds ([#5469][])
20
+ * Profiling: Improve profiling error message when another profiler is present ([#5375][])
21
+
22
+ ### Fixed
23
+
24
+ * Tracing: Integrations: Fix `endpoint_render.grape` ActiveSupport notification instrumentation for `grape` 3.x ([#5414][])
25
+ * Tracing: Integrations: Fix compatibility with `dalli` version 5.x and later ([#5435][])
26
+ * Dynamic Instrumentation: Fix JSON serialization failures when snapshots contain binary data and invalid UTF-8 strings ([#5434][])
27
+ * Dynamic Instrumentation: Show ERROR probe status when custom serializers produce non-JSON-encodable data instead of silent failures ([#5448][])
28
+ * Data Streams: Fix Data Streams Monitoring to correctly report the configured environment instead of showing `env:none` ([#5427][])
29
+
5
30
  ## [2.29.0] - 2026-02-20
6
31
 
7
32
 
@@ -3514,7 +3539,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
3514
3539
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3515
3540
 
3516
3541
 
3517
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.29.0...master
3542
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.30.0...master
3543
+ [2.30.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.29.0...v2.30.0
3518
3544
  [2.29.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.28.0...v2.29.0
3519
3545
  [2.28.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.27.0...v2.28.0
3520
3546
  [2.27.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.26.0...v2.27.0
@@ -5194,6 +5220,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
5194
5220
  [#5247]: https://github.com/DataDog/dd-trace-rb/issues/5247
5195
5221
  [#5254]: https://github.com/DataDog/dd-trace-rb/issues/5254
5196
5222
  [#5273]: https://github.com/DataDog/dd-trace-rb/issues/5273
5223
+ [#5274]: https://github.com/DataDog/dd-trace-rb/issues/5274
5197
5224
  [#5278]: https://github.com/DataDog/dd-trace-rb/issues/5278
5198
5225
  [#5283]: https://github.com/DataDog/dd-trace-rb/issues/5283
5199
5226
  [#5294]: https://github.com/DataDog/dd-trace-rb/issues/5294
@@ -5207,9 +5234,24 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
5207
5234
  [#5341]: https://github.com/DataDog/dd-trace-rb/issues/5341
5208
5235
  [#5342]: https://github.com/DataDog/dd-trace-rb/issues/5342
5209
5236
  [#5347]: https://github.com/DataDog/dd-trace-rb/issues/5347
5237
+ [#5351]: https://github.com/DataDog/dd-trace-rb/issues/5351
5210
5238
  [#5352]: https://github.com/DataDog/dd-trace-rb/issues/5352
5211
5239
  [#5368]: https://github.com/DataDog/dd-trace-rb/issues/5368
5212
5240
  [#5371]: https://github.com/DataDog/dd-trace-rb/issues/5371
5241
+ [#5375]: https://github.com/DataDog/dd-trace-rb/issues/5375
5242
+ [#5396]: https://github.com/DataDog/dd-trace-rb/issues/5396
5243
+ [#5414]: https://github.com/DataDog/dd-trace-rb/issues/5414
5244
+ [#5424]: https://github.com/DataDog/dd-trace-rb/issues/5424
5245
+ [#5425]: https://github.com/DataDog/dd-trace-rb/issues/5425
5246
+ [#5427]: https://github.com/DataDog/dd-trace-rb/issues/5427
5247
+ [#5432]: https://github.com/DataDog/dd-trace-rb/issues/5432
5248
+ [#5434]: https://github.com/DataDog/dd-trace-rb/issues/5434
5249
+ [#5435]: https://github.com/DataDog/dd-trace-rb/issues/5435
5250
+ [#5436]: https://github.com/DataDog/dd-trace-rb/issues/5436
5251
+ [#5448]: https://github.com/DataDog/dd-trace-rb/issues/5448
5252
+ [#5449]: https://github.com/DataDog/dd-trace-rb/issues/5449
5253
+ [#5461]: https://github.com/DataDog/dd-trace-rb/issues/5461
5254
+ [#5469]: https://github.com/DataDog/dd-trace-rb/issues/5469
5213
5255
  [@AdrianLC]: https://github.com/AdrianLC
5214
5256
  [@Azure7111]: https://github.com/Azure7111
5215
5257
  [@BabyGroot]: https://github.com/BabyGroot
@@ -5364,4 +5406,4 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
5364
5406
  [@y-yagi]: https://github.com/y-yagi
5365
5407
  [@yujideveloper]: https://github.com/yujideveloper
5366
5408
  [@yukimurasawa]: https://github.com/yukimurasawa
5367
- [@zachmccormick]: https://github.com/zachmccormick
5409
+ [@zachmccormick]: https://github.com/zachmccormick
@@ -102,6 +102,7 @@ typedef struct {
102
102
  bool gvl_profiling_enabled;
103
103
  bool skip_idle_samples_for_testing;
104
104
  bool sighandler_sampling_enabled;
105
+ uint32_t cpu_sampling_interval_ms;
105
106
  VALUE self_instance;
106
107
  VALUE thread_context_collector_instance;
107
108
  VALUE idle_sampling_helper_instance;
@@ -239,16 +240,16 @@ static VALUE _native_delayed_error(DDTRACE_UNUSED VALUE self, VALUE instance, VA
239
240
  static VALUE _native_hold_signals(DDTRACE_UNUSED VALUE self);
240
241
  static VALUE _native_resume_signals(DDTRACE_UNUSED VALUE self);
241
242
  #ifndef NO_GVL_INSTRUMENTATION
242
- static void on_gvl_event(rb_event_flag_t event_id, const rb_internal_thread_event_data_t *event_data, DDTRACE_UNUSED void *_unused);
243
- static void after_gvl_running_from_postponed_job(DDTRACE_UNUSED void *_unused);
243
+ static void on_gvl_event(rb_event_flag_t event_id, const rb_internal_thread_event_data_t *event_data, DDTRACE_UNUSED void *_unused);
244
+ static void after_gvl_running_from_postponed_job(DDTRACE_UNUSED void *_unused);
245
+ static VALUE rescued_after_gvl_running_from_postponed_job(VALUE self_instance);
246
+ static VALUE handle_sampling_failure_rescued_after_gvl_running_from_postponed_job(VALUE self_instance, VALUE exception);
244
247
  #endif
245
- static VALUE rescued_after_gvl_running_from_postponed_job(VALUE self_instance);
246
248
  static VALUE _native_gvl_profiling_hook_active(DDTRACE_UNUSED VALUE self, VALUE instance);
247
249
  static VALUE handle_sampling_failure_rescued_sample_from_postponed_job(VALUE self_instance, VALUE exception);
248
250
  static VALUE handle_sampling_failure_thread_context_collector_sample_after_gc(VALUE self_instance, VALUE exception);
249
251
  static VALUE handle_sampling_failure_rescued_sample_allocation(VALUE self_instance, VALUE exception);
250
252
  static VALUE handle_sampling_failure_rescued_after_allocation(VALUE self_instance, VALUE exception);
251
- static VALUE handle_sampling_failure_rescued_after_gvl_running_from_postponed_job(VALUE self_instance, VALUE exception);
252
253
  static inline void during_sample_enter(cpu_and_wall_time_worker_state* state);
253
254
  static inline void during_sample_exit(cpu_and_wall_time_worker_state* state);
254
255
  static void after_allocation_from_postponed_job(DDTRACE_UNUSED void *_unused);
@@ -383,6 +384,7 @@ static VALUE _native_new(VALUE klass) {
383
384
  state->gvl_profiling_enabled = false;
384
385
  state->skip_idle_samples_for_testing = false;
385
386
  state->sighandler_sampling_enabled = false;
387
+ state->cpu_sampling_interval_ms = 10;
386
388
  state->thread_context_collector_instance = Qnil;
387
389
  state->idle_sampling_helper_instance = Qnil;
388
390
  state->owner_thread = Qnil;
@@ -427,6 +429,7 @@ static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _sel
427
429
  VALUE gvl_profiling_enabled = rb_hash_fetch(options, ID2SYM(rb_intern("gvl_profiling_enabled")));
428
430
  VALUE skip_idle_samples_for_testing = rb_hash_fetch(options, ID2SYM(rb_intern("skip_idle_samples_for_testing")));
429
431
  VALUE sighandler_sampling_enabled = rb_hash_fetch(options, ID2SYM(rb_intern("sighandler_sampling_enabled")));
432
+ VALUE cpu_sampling_interval_ms = rb_hash_fetch(options, ID2SYM(rb_intern("cpu_sampling_interval_ms")));
430
433
 
431
434
  ENFORCE_BOOLEAN(gc_profiling_enabled);
432
435
  ENFORCE_BOOLEAN(no_signals_workaround_enabled);
@@ -437,6 +440,7 @@ static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _sel
437
440
  ENFORCE_BOOLEAN(gvl_profiling_enabled);
438
441
  ENFORCE_BOOLEAN(skip_idle_samples_for_testing)
439
442
  ENFORCE_BOOLEAN(sighandler_sampling_enabled)
443
+ ENFORCE_TYPE(cpu_sampling_interval_ms, T_FIXNUM);
440
444
 
441
445
  cpu_and_wall_time_worker_state *state;
442
446
  TypedData_Get_Struct(self_instance, cpu_and_wall_time_worker_state, &cpu_and_wall_time_worker_typed_data, state);
@@ -449,6 +453,7 @@ static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _sel
449
453
  state->gvl_profiling_enabled = (gvl_profiling_enabled == Qtrue);
450
454
  state->skip_idle_samples_for_testing = (skip_idle_samples_for_testing == Qtrue);
451
455
  state->sighandler_sampling_enabled = (sighandler_sampling_enabled == Qtrue);
456
+ state->cpu_sampling_interval_ms = NUM2INT(cpu_sampling_interval_ms);
452
457
 
453
458
  double total_overhead_target_percentage = NUM2DBL(dynamic_sampling_rate_overhead_target_percentage);
454
459
  if (!state->allocation_profiling_enabled) {
@@ -556,8 +561,9 @@ static VALUE _native_sampling_loop(DDTRACE_UNUSED VALUE _self, VALUE instance) {
556
561
  // @ivoanjo: I suspect this will never happen, but the cost of getting it wrong is really high (VM terminates) so this
557
562
  // is a just-in-case situation.
558
563
  //
559
- // Note 2: This can raise exceptions as well, so make sure that all cleanups are done by the time we get here.
560
- replace_sigprof_signal_handler_with_empty_handler(handle_sampling_signal);
564
+ // Note 2: If exception_state is set, we have a pending exception that we'll re-raise below.
565
+ // In that case, we don't want replace_sigprof_signal_handler_with_empty_handler to raise another exception.
566
+ replace_sigprof_signal_handler_with_empty_handler(handle_sampling_signal, !exception_state);
561
567
 
562
568
  // Ensure that instance is not garbage collected while the native sampling loop is running; this is probably not needed, but just in case
563
569
  RB_GC_GUARD(instance);
@@ -668,7 +674,7 @@ static void handle_sampling_signal(DDTRACE_UNUSED int _signal, DDTRACE_UNUSED si
668
674
  static void *run_sampling_trigger_loop(void *state_ptr) {
669
675
  cpu_and_wall_time_worker_state *state = (cpu_and_wall_time_worker_state *) state_ptr;
670
676
 
671
- uint64_t minimum_time_between_signals = MILLIS_AS_NS(10);
677
+ uint64_t minimum_time_between_signals = MILLIS_AS_NS(state->cpu_sampling_interval_ms);
672
678
 
673
679
  while (atomic_load(&state->should_run)) {
674
680
  state->stats.trigger_sample_attempts++;
@@ -1469,6 +1475,11 @@ static VALUE _native_resume_signals(DDTRACE_UNUSED VALUE self) {
1469
1475
 
1470
1476
  return state->gvl_profiling_hook != NULL ? Qtrue : Qfalse;
1471
1477
  }
1478
+
1479
+ static VALUE handle_sampling_failure_rescued_after_gvl_running_from_postponed_job(VALUE self_instance, VALUE exception) {
1480
+ stop(self_instance, exception, "rescued_after_gvl_running_from_postponed_job");
1481
+ return Qnil;
1482
+ }
1472
1483
  #else
1473
1484
  static VALUE _native_gvl_profiling_hook_active(DDTRACE_UNUSED VALUE self, DDTRACE_UNUSED VALUE instance) {
1474
1485
  return Qfalse;
@@ -1495,11 +1506,6 @@ static VALUE handle_sampling_failure_rescued_after_allocation(VALUE self_instanc
1495
1506
  return Qnil;
1496
1507
  }
1497
1508
 
1498
- static VALUE handle_sampling_failure_rescued_after_gvl_running_from_postponed_job(VALUE self_instance, VALUE exception) {
1499
- stop(self_instance, exception, "rescued_after_gvl_running_from_postponed_job");
1500
- return Qnil;
1501
- }
1502
-
1503
1509
  static VALUE rescued_after_allocation(VALUE self_instance) {
1504
1510
  cpu_and_wall_time_worker_state *state;
1505
1511
  TypedData_Get_Struct(self_instance, cpu_and_wall_time_worker_state, &cpu_and_wall_time_worker_typed_data, state);
@@ -1513,6 +1519,8 @@ static VALUE rescued_after_allocation(VALUE self_instance) {
1513
1519
  // This postponed job callback is used to finalize heap allocation recordings on Ruby 4+.
1514
1520
  // During on_newobj_event, calling rb_obj_id() is unsafe because it mutates the object.
1515
1521
  // So we defer getting the object_id until after the event completes.
1522
+ #pragma GCC diagnostic push
1523
+ #pragma GCC diagnostic ignored "-Wunused-function" // This is only used for some Rubies, but we want to build on all to make it easier to dev
1516
1524
  static void after_allocation_from_postponed_job(DDTRACE_UNUSED void *_unused) {
1517
1525
  cpu_and_wall_time_worker_state *state = active_sampler_instance_state;
1518
1526
 
@@ -1535,6 +1543,7 @@ static void after_allocation_from_postponed_job(DDTRACE_UNUSED void *_unused) {
1535
1543
 
1536
1544
  during_sample_exit(state);
1537
1545
  }
1546
+ #pragma GCC diagnostic pop
1538
1547
 
1539
1548
  static inline void during_sample_enter(cpu_and_wall_time_worker_state* state) {
1540
1549
  // Tell the compiler it's not allowed to reorder the `during_sample` flag with anything that happens after.
@@ -290,11 +290,13 @@ static bool handle_gvl_waiting(
290
290
  sampling_buffer* sampling_buffer,
291
291
  long current_cpu_time_ns
292
292
  );
293
- static VALUE _native_on_gvl_waiting(DDTRACE_UNUSED VALUE self, VALUE thread);
294
- static VALUE _native_gvl_waiting_at_for(DDTRACE_UNUSED VALUE self, VALUE thread);
295
- static VALUE _native_on_gvl_running(DDTRACE_UNUSED VALUE self, VALUE thread);
296
- static VALUE _native_sample_after_gvl_running(DDTRACE_UNUSED VALUE self, VALUE collector_instance, VALUE thread, VALUE allow_exception);
297
- static VALUE _native_apply_delta_to_cpu_time_at_previous_sample_ns(DDTRACE_UNUSED VALUE self, VALUE collector_instance, VALUE thread, VALUE delta_ns);
293
+ #ifndef NO_GVL_INSTRUMENTATION
294
+ static VALUE _native_on_gvl_waiting(DDTRACE_UNUSED VALUE self, VALUE thread);
295
+ static VALUE _native_gvl_waiting_at_for(DDTRACE_UNUSED VALUE self, VALUE thread);
296
+ static VALUE _native_on_gvl_running(DDTRACE_UNUSED VALUE self, VALUE thread);
297
+ static VALUE _native_sample_after_gvl_running(DDTRACE_UNUSED VALUE self, VALUE collector_instance, VALUE thread, VALUE allow_exception);
298
+ static VALUE _native_apply_delta_to_cpu_time_at_previous_sample_ns(DDTRACE_UNUSED VALUE self, VALUE collector_instance, VALUE thread, VALUE delta_ns);
299
+ #endif
298
300
  static void otel_without_ddtrace_trace_identifiers_for(
299
301
  thread_context_collector_state *state,
300
302
  VALUE thread,
@@ -1818,7 +1820,7 @@ static void otel_without_ddtrace_trace_identifiers_for(
1818
1820
  VALUE otel_current_span_key = get_otel_current_span_key(state, is_safe_to_allocate_objects);
1819
1821
  if (otel_current_span_key == Qnil) return;
1820
1822
 
1821
- int active_context_index = RARRAY_LEN(context_storage) - 1;
1823
+ long active_context_index = RARRAY_LEN(context_storage) - 1;
1822
1824
  if (active_context_index < 0) return;
1823
1825
 
1824
1826
  otel_span active_span = otel_span_from(rb_ary_entry(context_storage, active_context_index), otel_current_span_key);
@@ -1827,7 +1829,7 @@ static void otel_without_ddtrace_trace_identifiers_for(
1827
1829
  otel_span local_root_span = active_span;
1828
1830
 
1829
1831
  // Now find the oldest span starting from the active span that still has the same trace id as the active span
1830
- for (int i = active_context_index - 1; i >= 0; i--) {
1832
+ for (long i = active_context_index - 1; i >= 0; i--) {
1831
1833
  otel_span checking_span = otel_span_from(rb_ary_entry(context_storage, i), otel_current_span_key);
1832
1834
  if (checking_span.span == Qnil) return;
1833
1835
 
@@ -82,7 +82,8 @@ append_cflags "-Werror" if ENV["DATADOG_GEM_CI"] == "true"
82
82
  # * by upstream Ruby -- search for gnu99 in the codebase
83
83
  # * by msgpack, another datadog gem dependency
84
84
  # (https://github.com/msgpack/msgpack-ruby/blob/18ce08f6d612fe973843c366ac9a0b74c4e50599/ext/msgpack/extconf.rb#L8)
85
- append_cflags "-std=gnu99"
85
+ # @ivoanjo: We could probably start using C11/gnu11 for non macOS-too but it's somewhat hard to validate so I chickened out for now
86
+ append_cflags RUBY_PLATFORM.include?('darwin') ? '-std=gnu11' : '-std=gnu99'
86
87
 
87
88
  # Gets really noisy when we include the MJIT header, let's omit it (TODO: Use #pragma GCC diagnostic instead?)
88
89
  append_cflags "-Wno-unused-function"
@@ -210,37 +211,16 @@ $defs << "-DNO_GVL_OWNER" if RUBY_VERSION < "2.6"
210
211
  $defs << "-DNO_THREAD_INVOKE_ARG" if RUBY_VERSION < "2.6"
211
212
 
212
213
  # If we got here, libdatadog is available and loaded
213
- ENV["PKG_CONFIG_PATH"] = "#{ENV["PKG_CONFIG_PATH"]}:#{Libdatadog.pkgconfig_folder}"
214
- Logging.message("[datadog] PKG_CONFIG_PATH set to #{ENV["PKG_CONFIG_PATH"].inspect}\n")
215
214
  $stderr.puts("Using libdatadog #{Libdatadog::VERSION} from #{Libdatadog.pkgconfig_folder}")
216
215
 
217
- unless pkg_config("datadog_profiling_with_rpath")
218
- Logging.message("[datadog] Ruby detected the pkg-config command is #{$PKGCONFIG.inspect}\n")
219
-
220
- skip_building_extension!(
221
- if Datadog::LibdatadogExtconfHelpers.pkg_config_missing?
222
- Datadog::Profiling::NativeExtensionHelpers::Supported::PKG_CONFIG_IS_MISSING
223
- else
224
- # Less specific error message
225
- Datadog::Profiling::NativeExtensionHelpers::Supported::FAILED_TO_CONFIGURE_LIBDATADOG
226
- end
227
- )
216
+ unless Datadog::LibdatadogExtconfHelpers.configure_libdatadog(extconf_folder: __dir__)
217
+ skip_building_extension!(Datadog::Profiling::NativeExtensionHelpers::Supported::FAILED_TO_CONFIGURE_LIBDATADOG)
228
218
  end
229
219
 
230
220
  unless have_type("atomic_int", ["stdatomic.h"])
231
221
  skip_building_extension!(Datadog::Profiling::NativeExtensionHelpers::Supported::COMPILER_ATOMIC_MISSING)
232
222
  end
233
223
 
234
- # See comments on the helper methods being used for why we need to additionally set this.
235
- # The extremely excessive escaping around ORIGIN below seems to be correct and was determined after a lot of
236
- # experimentation. We need to get these special characters across a lot of tools untouched...
237
- extra_relative_rpaths = [
238
- Datadog::LibdatadogExtconfHelpers.libdatadog_folder_relative_to_native_lib_folder(current_folder: __dir__),
239
- *Datadog::LibdatadogExtconfHelpers.libdatadog_folder_relative_to_ruby_extensions_folders,
240
- ]
241
- extra_relative_rpaths.each { |folder| $LDFLAGS += " -Wl,-rpath,$$$\\\\{ORIGIN\\}/#{folder.to_str}" }
242
- Logging.message("[datadog] After pkg-config $LDFLAGS were set to: #{$LDFLAGS.inspect}\n")
243
-
244
224
  # Tag the native extension library with the Ruby version and Ruby platform.
245
225
  # This makes it easier for development (avoids "oops I forgot to rebuild when I switched my Ruby") and ensures that
246
226
  # the wrong library is never loaded.
@@ -693,7 +693,7 @@ VALUE heap_recorder_state_snapshot(heap_recorder *heap_recorder) {
693
693
 
694
694
  typedef struct {
695
695
  heap_recorder *recorder;
696
- VALUE debug_str;
696
+ VALUE debug_ary;
697
697
  } debug_context;
698
698
 
699
699
  VALUE heap_recorder_testonly_debug(heap_recorder *heap_recorder) {
@@ -701,12 +701,12 @@ VALUE heap_recorder_testonly_debug(heap_recorder *heap_recorder) {
701
701
  raise_error(rb_eArgError, "heap_recorder is NULL");
702
702
  }
703
703
 
704
- VALUE debug_str = rb_str_new2("");
705
- debug_context context = (debug_context) {.recorder = heap_recorder, .debug_str = debug_str};
704
+ VALUE debug_ary = rb_ary_new();
705
+ debug_context context = (debug_context) {.recorder = heap_recorder, .debug_ary = debug_ary};
706
706
  st_foreach(heap_recorder->object_records, st_object_records_debug, (st_data_t) &context);
707
707
 
708
708
  return rb_ary_new_from_args(2,
709
- rb_ary_new_from_args(2, ID2SYM(rb_intern("records")), debug_str),
709
+ rb_ary_new_from_args(2, ID2SYM(rb_intern("records")), debug_ary),
710
710
  rb_ary_new_from_args(2, ID2SYM(rb_intern("state")), heap_recorder_state_snapshot(heap_recorder))
711
711
  );
712
712
  }
@@ -828,11 +828,10 @@ static int st_object_records_iterate(DDTRACE_UNUSED st_data_t key, st_data_t val
828
828
 
829
829
  static int st_object_records_debug(DDTRACE_UNUSED st_data_t key, st_data_t value, st_data_t extra) {
830
830
  debug_context *context = (debug_context*) extra;
831
- VALUE debug_str = context->debug_str;
832
831
 
833
832
  object_record *record = (object_record*) value;
834
833
 
835
- rb_str_catf(debug_str, "%"PRIsVALUE"\n", object_record_inspect(context->recorder, record));
834
+ rb_ary_push(context->debug_ary, object_record_inspect(context->recorder, record));
836
835
 
837
836
  return ST_CONTINUE;
838
837
  }
@@ -16,7 +16,11 @@ static VALUE library_version_string = Qnil;
16
16
 
17
17
  typedef struct {
18
18
  ddog_prof_ProfileExporter *exporter;
19
- ddog_prof_Request_Result *build_result;
19
+ ddog_prof_EncodedProfile *profile;
20
+ ddog_prof_Exporter_Slice_File files_to_compress_and_export;
21
+ ddog_CharSlice internal_metadata;
22
+ ddog_CharSlice info;
23
+ ddog_CharSlice *process_tags;
20
24
  ddog_CancellationToken *cancel_token;
21
25
  ddog_prof_Result_HttpStatus result;
22
26
  bool send_ran;
@@ -29,7 +33,6 @@ static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_r
29
33
  static VALUE _native_do_export(
30
34
  VALUE self,
31
35
  VALUE exporter_configuration,
32
- VALUE upload_timeout_milliseconds,
33
36
  VALUE flush
34
37
  );
35
38
  static void *call_exporter_without_gvl(void *call_args);
@@ -39,7 +42,7 @@ void http_transport_init(VALUE profiling_module) {
39
42
  VALUE http_transport_class = rb_define_class_under(profiling_module, "HttpTransport", rb_cObject);
40
43
 
41
44
  rb_define_singleton_method(http_transport_class, "_native_validate_exporter", _native_validate_exporter, 1);
42
- rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 3);
45
+ rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 2);
43
46
 
44
47
  ok_symbol = ID2SYM(rb_intern_const("ok"));
45
48
  error_symbol = ID2SYM(rb_intern_const("error"));
@@ -75,15 +78,31 @@ static ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration) {
75
78
  ENFORCE_TYPE(exporter_working_mode, T_SYMBOL);
76
79
  ID working_mode = SYM2ID(exporter_working_mode);
77
80
 
78
- if (working_mode == rb_intern("agentless")) {
79
- VALUE site = rb_ary_entry(exporter_configuration, 1);
80
- VALUE api_key = rb_ary_entry(exporter_configuration, 2);
81
+ VALUE timeout_milliseconds_value = rb_ary_entry(exporter_configuration, 1);
82
+ ENFORCE_TYPE(timeout_milliseconds_value, T_FIXNUM);
83
+ uint64_t timeout_milliseconds = NUM2ULONG(timeout_milliseconds_value);
84
+
85
+ VALUE use_system_dns = rb_ary_entry(exporter_configuration, 2);
86
+ ENFORCE_BOOLEAN(use_system_dns);
81
87
 
82
- return ddog_prof_Endpoint_agentless(char_slice_from_ruby_string(site), char_slice_from_ruby_string(api_key));
88
+ if (working_mode == rb_intern("agentless")) {
89
+ VALUE site = rb_ary_entry(exporter_configuration, 3);
90
+ VALUE api_key = rb_ary_entry(exporter_configuration, 4);
91
+
92
+ return ddog_prof_Endpoint_agentless(
93
+ char_slice_from_ruby_string(site),
94
+ char_slice_from_ruby_string(api_key),
95
+ timeout_milliseconds,
96
+ use_system_dns == Qtrue
97
+ );
83
98
  } else if (working_mode == rb_intern("agent")) {
84
- VALUE base_url = rb_ary_entry(exporter_configuration, 1);
99
+ VALUE base_url = rb_ary_entry(exporter_configuration, 3);
85
100
 
86
- return ddog_prof_Endpoint_agent(char_slice_from_ruby_string(base_url));
101
+ return ddog_prof_Endpoint_agent(
102
+ char_slice_from_ruby_string(base_url),
103
+ timeout_milliseconds,
104
+ use_system_dns == Qtrue
105
+ );
87
106
  } else {
88
107
  raise_error(rb_eArgError, "Failed to initialize transport: Unexpected working mode, expected :agentless or :agent");
89
108
  }
@@ -123,41 +142,18 @@ static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_r
123
142
 
124
143
  // Note: This function handles a bunch of libdatadog dynamically-allocated objects, so it MUST not use any Ruby APIs
125
144
  // which can raise exceptions, otherwise the objects will be leaked.
126
- static VALUE perform_export(
127
- ddog_prof_ProfileExporter *exporter,
128
- ddog_prof_EncodedProfile *profile,
129
- ddog_prof_Exporter_Slice_File files_to_compress_and_export,
130
- ddog_CharSlice internal_metadata,
131
- ddog_CharSlice info,
132
- ddog_CharSlice *process_tags
133
- ) {
134
- ddog_prof_Request_Result build_result = ddog_prof_Exporter_Request_build(
135
- exporter,
136
- profile,
137
- files_to_compress_and_export,
138
- /* files_to_export_unmodified: */ ddog_prof_Exporter_Slice_File_empty(),
139
- /* optional_additional_tags: */ NULL,
140
- /* optional_process_tags: */ process_tags,
141
- &internal_metadata,
142
- &info
143
- );
144
-
145
- if (build_result.tag == DDOG_PROF_REQUEST_RESULT_ERR_HANDLE_REQUEST) {
146
- ddog_prof_Exporter_drop(exporter);
147
- return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&build_result.err));
148
- }
149
-
145
+ static VALUE perform_export(call_exporter_without_gvl_arguments args) {
150
146
  ddog_CancellationToken cancel_token_request = ddog_CancellationToken_new();
151
147
  ddog_CancellationToken cancel_token_interrupt = ddog_CancellationToken_clone(&cancel_token_request);
152
148
 
153
149
  validate_token(cancel_token_request, __FILE__, __LINE__);
154
150
  validate_token(cancel_token_interrupt, __FILE__, __LINE__);
155
151
 
152
+ args.cancel_token = &cancel_token_request;
153
+ args.send_ran = false;
154
+
156
155
  // We'll release the Global VM Lock while we're calling send, so that the Ruby VM can continue to work while this
157
156
  // is pending
158
- call_exporter_without_gvl_arguments args =
159
- {.exporter = exporter, .build_result = &build_result, .cancel_token = &cancel_token_request, .send_ran = false};
160
-
161
157
  // We use rb_thread_call_without_gvl2 instead of rb_thread_call_without_gvl as the gvl2 variant never raises any
162
158
  // exceptions.
163
159
  //
@@ -182,18 +178,13 @@ static VALUE perform_export(
182
178
  // Cleanup exporter and token, no longer needed
183
179
  ddog_CancellationToken_drop(&cancel_token_request);
184
180
  ddog_CancellationToken_drop(&cancel_token_interrupt);
185
- ddog_prof_Exporter_drop(exporter);
181
+ ddog_prof_Exporter_drop(args.exporter);
186
182
 
187
183
  if (pending_exception) {
188
- // If we got here send did not run, so we need to explicitly dispose of the request
189
- ddog_prof_Exporter_Request_drop(&build_result.ok);
190
-
191
184
  // Let Ruby propagate the exception. This will not return.
192
185
  rb_jump_tag(pending_exception);
193
186
  }
194
187
 
195
- // The request itself does not need to be freed as libdatadog takes ownership of it as part of sending.
196
-
197
188
  ddog_prof_Result_HttpStatus result = args.result;
198
189
 
199
190
  return result.tag == DDOG_PROF_RESULT_HTTP_STATUS_OK_HTTP_STATUS ?
@@ -204,7 +195,6 @@ static VALUE perform_export(
204
195
  static VALUE _native_do_export(
205
196
  DDTRACE_UNUSED VALUE _self,
206
197
  VALUE exporter_configuration,
207
- VALUE upload_timeout_milliseconds,
208
198
  VALUE flush
209
199
  ) {
210
200
  VALUE encoded_profile = rb_funcall(flush, rb_intern("encoded_profile"), 0);
@@ -215,7 +205,6 @@ static VALUE _native_do_export(
215
205
  VALUE info_json = rb_funcall(flush, rb_intern("info_json"), 0);
216
206
  VALUE process_tags = rb_funcall(flush, rb_intern("process_tags"), 0);
217
207
 
218
- ENFORCE_TYPE(upload_timeout_milliseconds, T_FIXNUM);
219
208
  enforce_encoded_profile_instance(encoded_profile);
220
209
  ENFORCE_TYPE(code_provenance_file_name, T_STRING);
221
210
  ENFORCE_TYPE(tags_as_array, T_ARRAY);
@@ -227,8 +216,6 @@ static VALUE _native_do_export(
227
216
  bool have_code_provenance = !NIL_P(code_provenance_data);
228
217
  if (have_code_provenance) ENFORCE_TYPE(code_provenance_data, T_STRING);
229
218
 
230
- uint64_t timeout_milliseconds = NUM2ULONG(upload_timeout_milliseconds);
231
-
232
219
  int to_compress_length = have_code_provenance ? 1 : 0;
233
220
  ddog_prof_Exporter_File to_compress[to_compress_length];
234
221
  ddog_prof_Exporter_Slice_File files_to_compress_and_export = {.ptr = to_compress, .len = to_compress_length};
@@ -250,29 +237,29 @@ static VALUE _native_do_export(
250
237
  VALUE failure_tuple = handle_exporter_failure(exporter_result);
251
238
  if (!NIL_P(failure_tuple)) return failure_tuple;
252
239
 
253
- ddog_VoidResult timeout_result = ddog_prof_Exporter_set_timeout(&exporter_result.ok, timeout_milliseconds);
254
- if (timeout_result.tag == DDOG_VOID_RESULT_ERR) {
255
- // NOTE: Seems a bit harsh to fail the upload if we can't set a timeout. OTOH, this is only expected to fail
256
- // if the exporter is not well built. Because such a situation should already be caught above I think it's
257
- // preferable to leave this here as a virtually unreachable exception rather than ignoring it.
258
- ddog_prof_Exporter_drop(&exporter_result.ok);
259
- return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&timeout_result.err));
260
- }
261
-
262
- return perform_export(
263
- &exporter_result.ok,
264
- to_ddog_prof_EncodedProfile(encoded_profile),
265
- files_to_compress_and_export,
266
- internal_metadata,
267
- info,
268
- &process_tags_slice
269
- );
240
+ return perform_export((call_exporter_without_gvl_arguments) {
241
+ .exporter = &exporter_result.ok,
242
+ .profile = to_ddog_prof_EncodedProfile(encoded_profile),
243
+ .files_to_compress_and_export = files_to_compress_and_export,
244
+ .internal_metadata = internal_metadata,
245
+ .info = info,
246
+ .process_tags = &process_tags_slice
247
+ });
270
248
  }
271
249
 
272
250
  static void *call_exporter_without_gvl(void *call_args) {
273
251
  call_exporter_without_gvl_arguments *args = (call_exporter_without_gvl_arguments*) call_args;
274
252
 
275
- args->result = ddog_prof_Exporter_send(args->exporter, &args->build_result->ok, args->cancel_token);
253
+ args->result = ddog_prof_Exporter_send_blocking(
254
+ args->exporter,
255
+ args->profile,
256
+ args->files_to_compress_and_export,
257
+ /* optional_additional_tags: */ NULL,
258
+ /* optional_process_tags: */ args->process_tags,
259
+ &args->internal_metadata,
260
+ &args->info,
261
+ args->cancel_token
262
+ );
276
263
  args->send_ran = true;
277
264
 
278
265
  return NULL; // Unused
@@ -104,19 +104,6 @@ module Datadog
104
104
  suggested: CONTACT_SUPPORT,
105
105
  )
106
106
 
107
- # Validation for this check is done in extconf.rb because it relies on mkmf
108
- PKG_CONFIG_IS_MISSING = explain_issue(
109
- # ----------------------------------------------------------------------------+
110
- "the `pkg-config` system tool is missing.",
111
- "This issue can usually be fixed by installing one of the following:",
112
- "the `pkg-config` package on Homebrew and Debian/Ubuntu-based Linux;",
113
- "the `pkgconf` package on Arch and Alpine-based Linux;",
114
- "the `pkgconf-pkg-config` package on Fedora/Red Hat-based Linux.",
115
- "(Tip: When fixing this, ensure `pkg-config` is installed **before**",
116
- "running `bundle install`, and remember to clear any installed gems cache).",
117
- suggested: CONTACT_SUPPORT,
118
- )
119
-
120
107
  # Validation for this check is done in extconf.rb because it relies on mkmf
121
108
  COMPILER_ATOMIC_MISSING = explain_issue(
122
109
  "your C compiler is missing support for the <stdatomic.h> header.",
@@ -25,6 +25,7 @@ void encoded_profile_init(VALUE profiling_module);
25
25
  void http_transport_init(VALUE profiling_module);
26
26
  void stack_recorder_init(VALUE profiling_module);
27
27
  void crashtracking_runtime_stacks_init(void);
28
+ void setup_signal_handler_init(VALUE profiling_module);
28
29
 
29
30
  static VALUE native_working_p(VALUE self);
30
31
  static VALUE _native_grab_gvl_and_raise(DDTRACE_UNUSED VALUE _self, VALUE exception_class, VALUE test_message, VALUE test_message_arg, VALUE release_gvl);
@@ -62,6 +63,7 @@ void DDTRACE_EXPORT Init_datadog_profiling_native_extension(void) {
62
63
  rb_funcall(native_extension_module, rb_intern("private_class_method"), 1, ID2SYM(rb_intern("native_working?")));
63
64
 
64
65
  ruby_helpers_init();
66
+ setup_signal_handler_init(profiling_module);
65
67
  collectors_cpu_and_wall_time_worker_init(profiling_module);
66
68
  collectors_discrete_dynamic_sampler_init(profiling_module);
67
69
  collectors_dynamic_sampling_rate_init(profiling_module);
@@ -251,7 +253,7 @@ static VALUE _native_trigger_holding_the_gvl_signal_handler_on(DDTRACE_UNUSED VA
251
253
 
252
254
  ENFORCE_SUCCESS_GVL(pthread_mutex_unlock(&holding_the_gvl_signal_handler_mutex));
253
255
 
254
- replace_sigprof_signal_handler_with_empty_handler(holding_the_gvl_signal_handler);
256
+ replace_sigprof_signal_handler_with_empty_handler(holding_the_gvl_signal_handler, true);
255
257
 
256
258
  if (holding_the_gvl_signal_handler_result[0] == Qfalse) raise_error(rb_eRuntimeError, "Could not signal background_thread");
257
259