datadog 2.22.0 → 2.24.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 (212) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +100 -1
  3. data/ext/LIBDATADOG_DEVELOPMENT.md +1 -58
  4. data/ext/datadog_profiling_native_extension/collectors_stack.c +21 -5
  5. data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +239 -0
  6. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +1 -1
  7. data/ext/datadog_profiling_native_extension/extconf.rb +9 -4
  8. data/ext/datadog_profiling_native_extension/heap_recorder.c +1 -1
  9. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +12 -0
  10. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +4 -0
  11. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  12. data/ext/libdatadog_api/datadog_ruby_common.h +1 -1
  13. data/ext/libdatadog_api/feature_flags.c +554 -0
  14. data/ext/libdatadog_api/feature_flags.h +5 -0
  15. data/ext/libdatadog_api/init.c +2 -0
  16. data/ext/libdatadog_api/library_config.c +12 -11
  17. data/ext/libdatadog_extconf_helpers.rb +1 -1
  18. data/lib/datadog/appsec/api_security/route_extractor.rb +23 -6
  19. data/lib/datadog/appsec/api_security/sampler.rb +7 -4
  20. data/lib/datadog/appsec/assets/blocked.html +8 -0
  21. data/lib/datadog/appsec/assets/blocked.json +1 -1
  22. data/lib/datadog/appsec/assets/blocked.text +3 -1
  23. data/lib/datadog/appsec/assets.rb +1 -1
  24. data/lib/datadog/appsec/context.rb +2 -1
  25. data/lib/datadog/appsec/remote.rb +5 -9
  26. data/lib/datadog/appsec/response.rb +18 -4
  27. data/lib/datadog/appsec/security_engine/result.rb +2 -1
  28. data/lib/datadog/core/configuration/components.rb +30 -3
  29. data/lib/datadog/core/configuration/config_helper.rb +2 -2
  30. data/lib/datadog/core/configuration/deprecations.rb +2 -2
  31. data/lib/datadog/core/configuration/option_definition.rb +4 -2
  32. data/lib/datadog/core/configuration/options.rb +8 -5
  33. data/lib/datadog/core/configuration/settings.rb +28 -3
  34. data/lib/datadog/core/configuration/supported_configurations.rb +332 -302
  35. data/lib/datadog/core/ddsketch.rb +0 -2
  36. data/lib/datadog/core/environment/cgroup.rb +52 -25
  37. data/lib/datadog/core/environment/container.rb +140 -46
  38. data/lib/datadog/core/environment/ext.rb +7 -0
  39. data/lib/datadog/core/environment/process.rb +87 -0
  40. data/lib/datadog/core/feature_flags.rb +61 -0
  41. data/lib/datadog/core/rate_limiter.rb +9 -1
  42. data/lib/datadog/core/remote/client/capabilities.rb +7 -0
  43. data/lib/datadog/core/remote/client.rb +14 -6
  44. data/lib/datadog/core/remote/component.rb +6 -4
  45. data/lib/datadog/core/remote/configuration/content.rb +15 -2
  46. data/lib/datadog/core/remote/configuration/digest.rb +14 -7
  47. data/lib/datadog/core/remote/configuration/repository.rb +1 -1
  48. data/lib/datadog/core/remote/configuration/target.rb +13 -6
  49. data/lib/datadog/core/remote/transport/config.rb +4 -25
  50. data/lib/datadog/core/remote/transport/http/config.rb +10 -50
  51. data/lib/datadog/core/remote/transport/http/negotiation.rb +14 -44
  52. data/lib/datadog/core/remote/transport/http.rb +15 -24
  53. data/lib/datadog/core/remote/transport/negotiation.rb +8 -33
  54. data/lib/datadog/core/remote/worker.rb +25 -37
  55. data/lib/datadog/core/tag_builder.rb +0 -4
  56. data/lib/datadog/core/tag_normalizer.rb +84 -0
  57. data/lib/datadog/core/telemetry/component.rb +59 -16
  58. data/lib/datadog/core/telemetry/event/app_started.rb +86 -49
  59. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
  60. data/lib/datadog/core/telemetry/logger.rb +2 -2
  61. data/lib/datadog/core/telemetry/logging.rb +2 -8
  62. data/lib/datadog/core/telemetry/metrics_manager.rb +9 -0
  63. data/lib/datadog/core/telemetry/request.rb +17 -3
  64. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +3 -34
  65. data/lib/datadog/core/telemetry/transport/http.rb +21 -16
  66. data/lib/datadog/core/telemetry/transport/telemetry.rb +3 -11
  67. data/lib/datadog/core/telemetry/worker.rb +88 -32
  68. data/lib/datadog/core/transport/ext.rb +2 -0
  69. data/lib/datadog/core/transport/http/api/endpoint.rb +9 -4
  70. data/lib/datadog/core/transport/http/api/instance.rb +4 -21
  71. data/lib/datadog/core/transport/http/builder.rb +9 -5
  72. data/lib/datadog/core/transport/http/client.rb +80 -0
  73. data/lib/datadog/core/transport/http.rb +22 -19
  74. data/lib/datadog/core/transport/response.rb +9 -0
  75. data/lib/datadog/core/transport/transport.rb +90 -0
  76. data/lib/datadog/core/utils/array.rb +29 -0
  77. data/lib/datadog/{appsec/api_security → core/utils}/lru_cache.rb +10 -21
  78. data/lib/datadog/core/utils/network.rb +3 -1
  79. data/lib/datadog/core/utils/only_once_successful.rb +8 -2
  80. data/lib/datadog/core/utils/time.rb +1 -1
  81. data/lib/datadog/core/utils.rb +2 -0
  82. data/lib/datadog/core/workers/async.rb +10 -1
  83. data/lib/datadog/core/workers/interval_loop.rb +44 -3
  84. data/lib/datadog/core/workers/polling.rb +2 -0
  85. data/lib/datadog/core/workers/queue.rb +100 -1
  86. data/lib/datadog/data_streams/configuration/settings.rb +49 -0
  87. data/lib/datadog/data_streams/configuration.rb +11 -0
  88. data/lib/datadog/data_streams/ext.rb +11 -0
  89. data/lib/datadog/data_streams/extensions.rb +16 -0
  90. data/lib/datadog/data_streams/pathway_context.rb +169 -0
  91. data/lib/datadog/data_streams/processor.rb +509 -0
  92. data/lib/datadog/data_streams/transport/http/stats.rb +52 -0
  93. data/lib/datadog/data_streams/transport/http.rb +40 -0
  94. data/lib/datadog/data_streams/transport/stats.rb +46 -0
  95. data/lib/datadog/data_streams.rb +100 -0
  96. data/lib/datadog/di/component.rb +0 -16
  97. data/lib/datadog/di/contrib/active_record.rb +31 -5
  98. data/lib/datadog/di/el/compiler.rb +8 -4
  99. data/lib/datadog/di/el/evaluator.rb +1 -1
  100. data/lib/datadog/di/error.rb +9 -0
  101. data/lib/datadog/di/instrumenter.rb +93 -34
  102. data/lib/datadog/di/probe.rb +20 -0
  103. data/lib/datadog/di/probe_builder.rb +2 -1
  104. data/lib/datadog/di/probe_manager.rb +47 -33
  105. data/lib/datadog/di/probe_notification_builder.rb +77 -25
  106. data/lib/datadog/di/proc_responder.rb +32 -0
  107. data/lib/datadog/di/remote.rb +89 -84
  108. data/lib/datadog/di/transport/diagnostics.rb +8 -36
  109. data/lib/datadog/di/transport/http/diagnostics.rb +1 -33
  110. data/lib/datadog/di/transport/http/input.rb +1 -33
  111. data/lib/datadog/di/transport/http.rb +32 -17
  112. data/lib/datadog/di/transport/input.rb +67 -34
  113. data/lib/datadog/di.rb +61 -5
  114. data/lib/datadog/open_feature/component.rb +60 -0
  115. data/lib/datadog/open_feature/configuration.rb +27 -0
  116. data/lib/datadog/open_feature/evaluation_engine.rb +70 -0
  117. data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
  118. data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
  119. data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
  120. data/lib/datadog/open_feature/exposures/event.rb +60 -0
  121. data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
  122. data/lib/datadog/open_feature/exposures/worker.rb +116 -0
  123. data/lib/datadog/open_feature/ext.rb +14 -0
  124. data/lib/datadog/open_feature/native_evaluator.rb +38 -0
  125. data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
  126. data/lib/datadog/open_feature/provider.rb +141 -0
  127. data/lib/datadog/open_feature/remote.rb +67 -0
  128. data/lib/datadog/open_feature/resolution_details.rb +35 -0
  129. data/lib/datadog/open_feature/transport.rb +70 -0
  130. data/lib/datadog/open_feature.rb +19 -0
  131. data/lib/datadog/opentelemetry/api/baggage.rb +1 -1
  132. data/lib/datadog/opentelemetry/configuration/settings.rb +159 -0
  133. data/lib/datadog/opentelemetry/metrics.rb +117 -0
  134. data/lib/datadog/opentelemetry/sdk/configurator.rb +25 -1
  135. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +35 -0
  136. data/lib/datadog/opentelemetry.rb +3 -0
  137. data/lib/datadog/profiling/collectors/code_provenance.rb +41 -7
  138. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +1 -1
  139. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -1
  140. data/lib/datadog/profiling/collectors/info.rb +2 -1
  141. data/lib/datadog/profiling/component.rb +12 -11
  142. data/lib/datadog/profiling/http_transport.rb +4 -1
  143. data/lib/datadog/profiling/profiler.rb +4 -0
  144. data/lib/datadog/profiling/tag_builder.rb +36 -3
  145. data/lib/datadog/profiling.rb +1 -2
  146. data/lib/datadog/single_step_instrument.rb +1 -1
  147. data/lib/datadog/tracing/configuration/ext.rb +9 -0
  148. data/lib/datadog/tracing/configuration/settings.rb +74 -0
  149. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +4 -4
  150. data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -2
  151. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +21 -7
  152. data/lib/datadog/tracing/contrib/active_job/patcher.rb +5 -1
  153. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +4 -2
  154. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -1
  155. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +11 -3
  156. data/lib/datadog/tracing/contrib/extensions.rb +10 -2
  157. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +11 -7
  158. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +7 -3
  159. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +22 -17
  160. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +11 -3
  161. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +11 -3
  162. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +11 -3
  163. data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +66 -0
  164. data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +66 -0
  165. data/lib/datadog/tracing/contrib/kafka/patcher.rb +14 -0
  166. data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
  167. data/lib/datadog/tracing/contrib/karafka/monitor.rb +11 -0
  168. data/lib/datadog/tracing/contrib/karafka/patcher.rb +35 -4
  169. data/lib/datadog/tracing/contrib/rack/middlewares.rb +59 -27
  170. data/lib/datadog/tracing/contrib/rack/route_inference.rb +53 -0
  171. data/lib/datadog/tracing/contrib/rails/middlewares.rb +2 -2
  172. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +4 -1
  173. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +3 -1
  174. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -1
  175. data/lib/datadog/tracing/contrib/status_range_matcher.rb +9 -1
  176. data/lib/datadog/tracing/contrib/utils/quantization/hash.rb +3 -1
  177. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +27 -0
  178. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +48 -0
  179. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +17 -0
  180. data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
  181. data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
  182. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +49 -0
  183. data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
  184. data/lib/datadog/tracing/contrib/waterdrop.rb +37 -0
  185. data/lib/datadog/tracing/contrib.rb +1 -0
  186. data/lib/datadog/tracing/diagnostics/environment_logger.rb +1 -1
  187. data/lib/datadog/tracing/metadata/ext.rb +1 -1
  188. data/lib/datadog/tracing/remote.rb +1 -9
  189. data/lib/datadog/tracing/span_event.rb +2 -2
  190. data/lib/datadog/tracing/span_operation.rb +9 -4
  191. data/lib/datadog/tracing/trace_operation.rb +44 -6
  192. data/lib/datadog/tracing/tracer.rb +42 -16
  193. data/lib/datadog/tracing/transport/http/client.rb +12 -26
  194. data/lib/datadog/tracing/transport/http/traces.rb +2 -50
  195. data/lib/datadog/tracing/transport/http.rb +15 -9
  196. data/lib/datadog/tracing/transport/io/client.rb +1 -1
  197. data/lib/datadog/tracing/transport/trace_formatter.rb +11 -0
  198. data/lib/datadog/tracing/transport/traces.rb +9 -71
  199. data/lib/datadog/tracing/workers/trace_writer.rb +5 -0
  200. data/lib/datadog/tracing/writer.rb +1 -0
  201. data/lib/datadog/version.rb +2 -2
  202. data/lib/datadog.rb +2 -0
  203. metadata +78 -21
  204. data/lib/datadog/core/remote/transport/http/api.rb +0 -53
  205. data/lib/datadog/core/remote/transport/http/client.rb +0 -49
  206. data/lib/datadog/core/telemetry/transport/http/api.rb +0 -43
  207. data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
  208. data/lib/datadog/core/transport/http/api/spec.rb +0 -36
  209. data/lib/datadog/di/transport/http/api.rb +0 -42
  210. data/lib/datadog/di/transport/http/client.rb +0 -47
  211. data/lib/datadog/opentelemetry/api/baggage.rbs +0 -26
  212. data/lib/datadog/tracing/transport/http/api.rb +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 495f03c8c90a6786ec765ac781553fe5197d9511586a41964382b73bb69ccca9
4
- data.tar.gz: 81c46a4063b395a010ad1a028289b74c2d55bdaa6dff36ce61085d066a9b1a19
3
+ metadata.gz: a1e3df0d4845537939ee39a49f98f9645cf0b5f3cd8f62cd9b7c8dd7f7cf112f
4
+ data.tar.gz: e84c39b5b0d3b464aa5d9c1d050a215374520575832bee48671549bbf9696973
5
5
  SHA512:
6
- metadata.gz: 2d4ab14bf55177e33f186c762b5156dd8cb8c17471c6277e1e0d1bce444212c98d221e00a2150fb3358203c898bb40fe431e9ebca0ef8fd22feec80758f8e922
7
- data.tar.gz: 505dd3f5f5a08a18a95aef5cb7ae979c63bee58b22d36b8d77b21b0b5998ef775ec8c437895633355664a5ac0c31a9c2624b73ef08b63fa4154712508411b172
6
+ metadata.gz: f00d5556de98278dc5f80d1146374b378e6d21e32c041239e0e6a6237f4169d79061f1e94df1f8221255a2a807ed6a3ff6f80668ff3421030737c6ec7bf35f76
7
+ data.tar.gz: 94a76fd5432c238ee71c261419cb99e943143e802092ba0ec4aa9391e988f5ed6e9c307295211f0c16951d47e060633b62b40f982c83834aa179b6e66b03af91
data/CHANGELOG.md CHANGED
@@ -2,6 +2,64 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [2.24.0] - 2026-01-08
6
+
7
+ ### Added
8
+
9
+ * Core: Add support for installing the gem on Ruby 4.0.x stable ([#5157][])
10
+ * Tracing: Add origin detection using extra headers and the `DD_EXTERNAL_ENV` variable. ([#5028][])
11
+ * Dynamic Instrumentation: Add one-click enablement support ([#5150][])
12
+
13
+ ### Changed
14
+
15
+ * Profiling: Remove profiler warning related to the Ractor issue ([#5194][])
16
+ * Profiling: Disable heap profiling on Ruby 4 due to incompatibility ([#5148][])
17
+ * Dynamic Instrumentation: Stop using customer-provided time provider for method duration calculation ([#5153][])
18
+ * Live Debugger / Dynamic Instrumentation: Improve probe instrumentation ([#5165][])
19
+ * Live Debugger / Dynamic Instrumentation: Improve instrumentation reliability for probes ([#5169][])
20
+
21
+ ### Fixed
22
+
23
+ * Core: Improve reliability of worker shutdown ([#5176][])
24
+ * Core: Fix RDoc error when installing the `datadog` gem ([#5145][])
25
+ * Tracing: Ensure `Tracing.continue_from!` keeps the active trace for the full block duration. ([#4941][])
26
+ * Profiling: Fix and refine profiler thread state categorization for Ruby 4 ([#5197][])
27
+ * Profiling: Fix profiler error triggering `Bundler::PermissionError` ([#5146][])
28
+ * Live Debugger / Dynamic Instrumentation: Fix Live Debugger and Dynamic Instrumentation UI for forking web servers ([#5159][])
29
+ * Live Debugger / Dynamic Instrumentation: Fix method probe leak when a referenced class loads after the probe reaches the application ([#5168][])
30
+
31
+ ## [2.23.0] - 2025-12-11
32
+
33
+ ### Added
34
+
35
+ * Tracing: Add process tags to trace payloads with `DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED` environment variable ([#5033][])
36
+ * Tracing: Integrations: Add Data Streams Monitoring (DSM) instrumentation to Waterdrop producers ([#5031][])
37
+ * Tracing: Open Telemetry: Add OpenTelemetry metrics support with OTLP exporters using `DD_METRICS_OTEL_ENABLED` and standard OpenTelemetry environment variables ([#5021][])
38
+ * Tracing: Add `http.endpoint` tag which contains the route whenever routing info is available, and falls back to route inferred from the request path ([#4995][])
39
+ * Tracing: Add configuration of HTTP client and server error ranges via `DD_TRACE_HTTP_CLIENT_ERROR_STATUSES` and `DD_TRACE_HTTP_SERVER_ERROR_STATUSES` ([#4991][])
40
+ * Tracing: Integrations: Add Data Streams Monitoring for `ruby-kafka` and `karafka` consumers with optional manual instrumentation ([#4901][])
41
+ * Dynamic Instrumentation: Add support for Hash length operations in expression language ([#5019][])
42
+ * AppSec: Add unique security response identifier in the response body for blocked requests ([#5049][])
43
+ * AppSec: Add support for processor overrides and custom data scanners ([#5044][])
44
+ * Feature Flags: Add new component to support Open Feature SDK ([#5054][], [#5024][])
45
+
46
+ ### Changed
47
+
48
+ * Core: Update minimum `datadog-ruby_core_source` dependency to 3.4.2 ([#5122][])
49
+ * Core: Update `libdatadog` dependency to version 24.0.1 ([#5058][], [#5045][], [#5020][])
50
+ * Tracing: Treat IPs from `100.65.0.0/10` range as private. ([#4975][])
51
+
52
+ ### Fixed
53
+
54
+ * Live Debugger / Dynamic Instrumentation: Fix issues delivering large quantities of snapshots ([#5086][])
55
+ * Tracing: Integrations: Fix `NoMethodError` in GraphQL integration when error has no `locations`. ([#5025][])
56
+ * Tracing: Integrations: Fix `http.route` tag for Rack applications mounted inside Rails. ([#4988][])
57
+ * Profiling: Fix profiler support for Ruby 4.0.0-preview2 ([#5091][])
58
+ * Profiling: Fix profiler sleep and wait states not being categorized in timeline ([#5000][])
59
+ * Profiling: Fix profiler not identifying executables with gems they belong to ([#4999][])
60
+ * Stable Config: Fix potential segfault during configuration file parsing ([#5073][])
61
+ * AppSec: Fix route extraction error for Rails 8.1.1+. ([#5042][])
62
+
5
63
  ## [2.22.0] - 2025-10-15
6
64
 
7
65
  ### Added
@@ -3360,7 +3418,9 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
3360
3418
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3361
3419
 
3362
3420
 
3363
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.22.0...master
3421
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.24.0...master
3422
+ [2.24.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.23.0...v2.24.0
3423
+ [2.23.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.22.0...v2.23.0
3364
3424
  [2.22.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.21.0...v2.22.0
3365
3425
  [2.21.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.20.0...v2.21.0
3366
3426
  [2.20.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.19.0...v2.20.0
@@ -4967,6 +5027,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4967
5027
  [#4893]: https://github.com/DataDog/dd-trace-rb/issues/4893
4968
5028
  [#4894]: https://github.com/DataDog/dd-trace-rb/issues/4894
4969
5029
  [#4900]: https://github.com/DataDog/dd-trace-rb/issues/4900
5030
+ [#4901]: https://github.com/DataDog/dd-trace-rb/issues/4901
4970
5031
  [#4902]: https://github.com/DataDog/dd-trace-rb/issues/4902
4971
5032
  [#4906]: https://github.com/DataDog/dd-trace-rb/issues/4906
4972
5033
  [#4907]: https://github.com/DataDog/dd-trace-rb/issues/4907
@@ -4976,9 +5037,47 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4976
5037
  [#4914]: https://github.com/DataDog/dd-trace-rb/issues/4914
4977
5038
  [#4918]: https://github.com/DataDog/dd-trace-rb/issues/4918
4978
5039
  [#4919]: https://github.com/DataDog/dd-trace-rb/issues/4919
5040
+ [#4941]: https://github.com/DataDog/dd-trace-rb/issues/4941
4979
5041
  [#4957]: https://github.com/DataDog/dd-trace-rb/issues/4957
4980
5042
  [#4965]: https://github.com/DataDog/dd-trace-rb/issues/4965
4981
5043
  [#4969]: https://github.com/DataDog/dd-trace-rb/issues/4969
5044
+ [#4975]: https://github.com/DataDog/dd-trace-rb/issues/4975
5045
+ [#4988]: https://github.com/DataDog/dd-trace-rb/issues/4988
5046
+ [#4991]: https://github.com/DataDog/dd-trace-rb/issues/4991
5047
+ [#4995]: https://github.com/DataDog/dd-trace-rb/issues/4995
5048
+ [#4999]: https://github.com/DataDog/dd-trace-rb/issues/4999
5049
+ [#5000]: https://github.com/DataDog/dd-trace-rb/issues/5000
5050
+ [#5019]: https://github.com/DataDog/dd-trace-rb/issues/5019
5051
+ [#5020]: https://github.com/DataDog/dd-trace-rb/issues/5020
5052
+ [#5021]: https://github.com/DataDog/dd-trace-rb/issues/5021
5053
+ [#5024]: https://github.com/DataDog/dd-trace-rb/issues/5024
5054
+ [#5025]: https://github.com/DataDog/dd-trace-rb/issues/5025
5055
+ [#5028]: https://github.com/DataDog/dd-trace-rb/issues/5028
5056
+ [#5031]: https://github.com/DataDog/dd-trace-rb/issues/5031
5057
+ [#5033]: https://github.com/DataDog/dd-trace-rb/issues/5033
5058
+ [#5042]: https://github.com/DataDog/dd-trace-rb/issues/5042
5059
+ [#5044]: https://github.com/DataDog/dd-trace-rb/issues/5044
5060
+ [#5045]: https://github.com/DataDog/dd-trace-rb/issues/5045
5061
+ [#5049]: https://github.com/DataDog/dd-trace-rb/issues/5049
5062
+ [#5054]: https://github.com/DataDog/dd-trace-rb/issues/5054
5063
+ [#5058]: https://github.com/DataDog/dd-trace-rb/issues/5058
5064
+ [#5073]: https://github.com/DataDog/dd-trace-rb/issues/5073
5065
+ [#5086]: https://github.com/DataDog/dd-trace-rb/issues/5086
5066
+ [#5091]: https://github.com/DataDog/dd-trace-rb/issues/5091
5067
+ [#5122]: https://github.com/DataDog/dd-trace-rb/issues/5122
5068
+ [#5145]: https://github.com/DataDog/dd-trace-rb/issues/5145
5069
+ [#5146]: https://github.com/DataDog/dd-trace-rb/issues/5146
5070
+ [#5148]: https://github.com/DataDog/dd-trace-rb/issues/5148
5071
+ [#5150]: https://github.com/DataDog/dd-trace-rb/issues/5150
5072
+ [#5153]: https://github.com/DataDog/dd-trace-rb/issues/5153
5073
+ [#5157]: https://github.com/DataDog/dd-trace-rb/issues/5157
5074
+ [#5159]: https://github.com/DataDog/dd-trace-rb/issues/5159
5075
+ [#5165]: https://github.com/DataDog/dd-trace-rb/issues/5165
5076
+ [#5168]: https://github.com/DataDog/dd-trace-rb/issues/5168
5077
+ [#5169]: https://github.com/DataDog/dd-trace-rb/issues/5169
5078
+ [#5176]: https://github.com/DataDog/dd-trace-rb/issues/5176
5079
+ [#5194]: https://github.com/DataDog/dd-trace-rb/issues/5194
5080
+ [#5197]: https://github.com/DataDog/dd-trace-rb/issues/5197
4982
5081
  [@AdrianLC]: https://github.com/AdrianLC
4983
5082
  [@Azure7111]: https://github.com/Azure7111
4984
5083
  [@BabyGroot]: https://github.com/BabyGroot
@@ -1,60 +1,3 @@
1
1
  # Libdatadog development
2
2
 
3
- These instructions can quickly get outdated, so feel free to open an issue if they're not working (and/or ping @ivoanjo).
4
-
5
- ## Using libdatadog builds from CI or GitHub
6
-
7
- If you're developing inside docker/natively on Linux, you can use libdatadog builds from CI and GitHub.
8
-
9
- Here's what to do:
10
-
11
- 1. Create a folder for extracting libdatadog into based on your ruby platform (for instance inside the dd-trace-rb repo):
12
-
13
- ```bash
14
- export DD_RUBY_PLATFORM=`ruby -e 'puts Gem::Platform.local.to_s'`
15
- echo "Current ruby platform: $DD_RUBY_PLATFORM"
16
- mkdir -p my-libdatadog-build/$DD_RUBY_PLATFORM
17
- ```
18
-
19
- 2. Find a libdatadog build from CI or [GitHub releases](https://github.com/DataDog/libdatadog/releases). This should match the Ruby platform seen above.
20
- 3. Extract the libdatadog build into the folder:
21
-
22
- ```bash
23
- # In this example the build is in my downloads; notice the use of strip-components to get the correct folder structure
24
- tar zxvf ~/Downloads/libdatadog-x86_64-unknown-linux-gnu.tar.gz -C my-libdatadog-build/$DD_RUBY_PLATFORM/ --strip-components=1
25
- # Here's how it should look after
26
- ls my-libdatadog-build/$DD_RUBY_PLATFORM
27
- bin cmake include lib LICENSE LICENSE-3rdparty.yml NOTICE
28
- ```
29
-
30
- 6. Tell Ruby where to find libdatadog: ```export LIBDATADOG_VENDOR_OVERRIDE=`pwd`/my-libdatadog-build/``` (Notice no platform + use of pwd for full path here)
31
- 7. From dd-trace-rb, run `bundle exec rake clean compile`
32
- 8. For incremental builds, usually `bundle exec rake compile` is faster and `clean` is not needed
33
-
34
- If you additionally want to run the profiler test suite, also remember to `export DD_PROFILING_MACOS_TESTING=true` and re-run `rake clean compile`.
35
-
36
- ## Native development on macOS
37
-
38
- As of this writing (August 2025), the libdatadog builds on rubygems.org only support Linux.
39
-
40
- We don't officially support using libdatadog for Ruby on other platforms yet, but it is possible to use it for local development on macOS.
41
- (**Note that you don't need these instructions if you develop inside docker.**)
42
-
43
- Here's how you can do so:
44
-
45
- 1. [Install rust](https://www.rust-lang.org/tools/install)
46
- 2. Install `cbindgen`: `cargo install cbindgen`
47
- 3. Clone [libdatadog](https://github.com/datadog/libdatadog)
48
- 4. Create a folder for building into based on your ruby platform:
49
-
50
- ```bash
51
- export DD_RUBY_PLATFORM=`ruby -e 'puts Gem::Platform.local.to_s'`
52
- mkdir -p my-libdatadog-build/$DD_RUBY_PLATFORM
53
- ```
54
-
55
- 5. From inside of the libdatadog repo, build libdatadog into this folder: `./build-profiling-ffi.sh my-libdatadog-build/$DD_RUBY_PLATFORM`
56
- 6. Tell Ruby where to find libdatadog: `export LIBDATADOG_VENDOR_OVERRIDE=/adjust/this/to/be/the/full/path/to/my-libdatadog-build/` (Notice no platform here)
57
- 7. From dd-trace-rb, run `bundle exec rake clean compile`
58
- 8. For incremental builds, usually `bundle exec rake compile` is faster and `clean` is not needed
59
-
60
- If you additionally want to run the profiler test suite, also remember to `export DD_PROFILING_MACOS_TESTING=true` and re-run `rake clean compile`.
3
+ Moved to <../docs/LibdatadogDevelopment.md>!
@@ -347,13 +347,19 @@ void sample_thread(
347
347
  } else if (CHARSLICE_EQUALS("select", name_slice)) { // Expected to be Kernel.select
348
348
  state_label->str = DDOG_CHARSLICE_C("waiting");
349
349
  } else if (
350
- CHARSLICE_EQUALS("synchronize", name_slice) || // Expected to be Monitor/Mutex#synchronize
351
- CHARSLICE_EQUALS("lock", name_slice) || // Expected to be Mutex#lock
350
+ CHARSLICE_EQUALS("synchronize", name_slice) || // Expected to be Monitor/Mutex#synchronize on Ruby 2 & 3, and Monitor#synchronize on 4 (Mutex becomes <internal:thread_sync>)
351
+ #ifdef NO_PRIMITIVE_MUTEX_AND_CONDITION_VARIABLE // Ruby < 4
352
+ CHARSLICE_EQUALS("lock", name_slice) || // Expected to be Mutex#lock
353
+ #endif
352
354
  CHARSLICE_EQUALS("join", name_slice) // Expected to be Thread#join
353
355
  ) {
354
356
  state_label->str = DDOG_CHARSLICE_C("blocked");
355
357
  } else if (CHARSLICE_EQUALS("wait_readable", name_slice)) { // Expected to be IO#wait_readable
356
358
  state_label->str = DDOG_CHARSLICE_C("network");
359
+ } else if (CHARSLICE_EQUALS("_native_idle_sampling_loop", name_slice)) { // Expected to be Datadog::Profiler::Collectors::IdleSamplingHelper#_native_idle_sampling_loop
360
+ state_label->str = DDOG_CHARSLICE_C("waiting");
361
+ } else if (CHARSLICE_EQUALS("_native_sampling_loop", name_slice)) { // Expected to be Datadog::Profiler::Collectors::CpuAndWallTimeWorker#_native_sampling_loop
362
+ state_label->str = DDOG_CHARSLICE_C("sleeping");
357
363
  }
358
364
  #ifdef NO_PRIMITIVE_POP // Ruby < 3.2
359
365
  else if (CHARSLICE_EQUALS("pop", name_slice)) { // Expected to be Queue/SizedQueue#pop
@@ -362,9 +368,19 @@ void sample_thread(
362
368
  #endif
363
369
  } else {
364
370
  #ifndef NO_PRIMITIVE_POP // Ruby >= 3.2
365
- // Unlike the above, Ruby actually treats this one specially and gives it a nice file name we can match on!
366
- if (CHARSLICE_EQUALS("pop", name_slice) && CHARSLICE_EQUALS("<internal:thread_sync>", filename_slice)) { // Expected to be Queue/SizedQueue#pop
367
- state_label->str = DDOG_CHARSLICE_C("waiting");
371
+ if (CHARSLICE_EQUALS("<internal:thread_sync>", filename_slice)) {
372
+ if (CHARSLICE_EQUALS("pop", name_slice)) { // Expected to be Queue/SizedQueue#pop
373
+ state_label->str = DDOG_CHARSLICE_C("waiting");
374
+ }
375
+ #ifndef NO_PRIMITIVE_MUTEX_AND_CONDITION_VARIABLE // Ruby >= 4
376
+ else if (CHARSLICE_EQUALS("synchronize", name_slice) || CHARSLICE_EQUALS("lock", name_slice)) { // Expected to be Mutex#lock/synchronize
377
+ state_label->str = DDOG_CHARSLICE_C("blocked");
378
+ } else if (CHARSLICE_EQUALS("sleep", name_slice)) { // Expected to be Mutex#sleep
379
+ state_label->str = DDOG_CHARSLICE_C("sleeping");
380
+ } else if (CHARSLICE_EQUALS("wait", name_slice)) { // Expected to be ConditionVariable#wait
381
+ state_label->str = DDOG_CHARSLICE_C("waiting");
382
+ }
383
+ #endif
368
384
  }
369
385
  #endif
370
386
  }
@@ -0,0 +1,239 @@
1
+ // NOTE: This file is a part of the profiling native extension even though the
2
+ // runtime stacks feature is consumed by the crashtracker. The profiling
3
+ // extension already carries all the Ruby VM private header access and build
4
+ // plumbing required to safely poke at internal structures. Sharing that setup
5
+ // avoids duplicating another native extension with the same (fragile) access
6
+ // patterns, and keeps the overall install/build surface area smaller.
7
+ //
8
+ // This also means that this functionality is depend on the profiling native extension
9
+ // being available and built
10
+ #include "extconf.h"
11
+
12
+ #if defined(__linux__)
13
+
14
+ #include <datadog/crashtracker.h>
15
+ #include "datadog_ruby_common.h"
16
+ #include "private_vm_api_access.h"
17
+ #include <sys/mman.h>
18
+ #include <unistd.h>
19
+ #include <errno.h>
20
+ #include <string.h>
21
+
22
+ static const rb_data_type_t *crashtracker_thread_data_type = NULL;
23
+
24
+ static void ruby_runtime_stack_callback(
25
+ void (*emit_frame)(const ddog_crasht_RuntimeStackFrame*)
26
+ );
27
+
28
+ // Use a fixed, preallocated buffer for crash-time runtime stacks to avoid
29
+ // heap allocation in the signal/crash path.
30
+ #define RUNTIME_STACK_MAX_FRAMES 512
31
+ static frame_info runtime_stack_buffer[RUNTIME_STACK_MAX_FRAMES];
32
+
33
+ #if defined(__x86_64__)
34
+ # define SYS_MINCORE 0x1B
35
+ #elif defined(__aarch64__)
36
+ # define SYS_MINCORE 0xE8
37
+ #endif
38
+
39
+ long syscall(long number, ...);
40
+
41
+ // align down to power of two
42
+ static inline uintptr_t align_down(uintptr_t x, uintptr_t align) {
43
+ return x & ~(align - 1u);
44
+ }
45
+
46
+ static uintptr_t cached_page_size = 0;
47
+
48
+ // TODO: This function is not necessarily Ruby specific. This will be moved to
49
+ // `libdatadog` in the future as a shared utility function.
50
+ static inline bool is_pointer_readable(const void *ptr, size_t size) {
51
+ if (!ptr || size == 0) return false;
52
+
53
+ uintptr_t page_size = cached_page_size;
54
+
55
+ const uintptr_t start = align_down((uintptr_t)ptr, page_size);
56
+ const uintptr_t end = ((uintptr_t)ptr + size - 1u);
57
+ const uintptr_t last = align_down(end, page_size);
58
+
59
+ // Number of pages spanned
60
+ size_t pages = 1u + (last != start);
61
+ if (pages > 2u) pages = 2u;
62
+
63
+ unsigned char vec[2];
64
+
65
+ int retries = 5;
66
+ for (;;) {
67
+ size_t len = pages * (size_t)page_size;
68
+ long rc = syscall(SYS_MINCORE, (void*)start, len, vec);
69
+
70
+ if (rc == 0) {
71
+ return true;
72
+ }
73
+
74
+ int e = errno;
75
+ if (e == ENOMEM || e == EFAULT) {
76
+ return false;
77
+ }
78
+
79
+ if (e == EAGAIN && retries-- > 0) {
80
+ continue;
81
+ }
82
+
83
+ // Unknown errno, we assume mapped to avoid cascading faults in crash path
84
+ return true;
85
+ }
86
+ }
87
+
88
+ static inline ddog_CharSlice char_slice_from_cstr(const char *cstr) {
89
+ if (cstr == NULL) {
90
+ return (ddog_CharSlice){.ptr = NULL, .len = 0};
91
+ }
92
+ return (ddog_CharSlice){.ptr = cstr, .len = strlen(cstr)};
93
+ }
94
+
95
+ static ddog_CharSlice safe_string_value(VALUE str) {
96
+ if (str == Qnil) return DDOG_CHARSLICE_C("<nil>");
97
+
98
+ // Validate object and payload readability in one check
99
+ if (!is_pointer_readable((const void *)str, sizeof(struct RString))) return DDOG_CHARSLICE_C("<corrupted>");
100
+ if (!RB_TYPE_P(str, T_STRING)) return DDOG_CHARSLICE_C("<not_string>");
101
+
102
+ long len = RSTRING_LEN(str);
103
+ if (len < 0 || len > 1024) return DDOG_CHARSLICE_C("<length_over_limit>");
104
+
105
+ const char *ptr = RSTRING_PTR(str);
106
+ if (!ptr) return DDOG_CHARSLICE_C("<null>");
107
+
108
+ if (!is_pointer_readable(ptr, len > 0 ? len : 1)) return DDOG_CHARSLICE_C("<unreadable>");
109
+
110
+ return (ddog_CharSlice){.ptr = ptr, .len = (size_t)len};
111
+ }
112
+
113
+ static void emit_placeholder_frame(
114
+ void (*emit_frame)(const ddog_crasht_RuntimeStackFrame*),
115
+ const char *label
116
+ ) {
117
+ ddog_crasht_RuntimeStackFrame frame = {
118
+ .type_name = DDOG_CHARSLICE_C(""),
119
+ .function = char_slice_from_cstr(label),
120
+ .file = DDOG_CHARSLICE_C("<unknown>"),
121
+ .line = 0,
122
+ .column = 0
123
+ };
124
+ emit_frame(&frame);
125
+ }
126
+
127
+ // Collect the crashing thread's frames via ddtrace_rb_profile_frames into a static buffer, then emit
128
+ // them newest-first. If corruption is detected, emit placeholder frames so the crash report still
129
+ // completes. We lean on the Ruby VM helpers we already use for profiling and rely on crashtracker's
130
+ // safety nets so a failure here should not impact customers.
131
+ static void ruby_runtime_stack_callback(
132
+ void (*emit_frame)(const ddog_crasht_RuntimeStackFrame*)
133
+ ) {
134
+ // Grab the Ruby thread we crashed on; crashtracker only runs once.
135
+ VALUE current_thread = rb_thread_current();
136
+ if (current_thread == Qnil) return;
137
+
138
+ if (crashtracker_thread_data_type == NULL) return;
139
+
140
+ if (!rb_typeddata_is_kind_of(current_thread, crashtracker_thread_data_type)) {
141
+ emit_placeholder_frame(emit_frame, "<runtime stack not found>");
142
+ return;
143
+ }
144
+
145
+ // Use the profiling helper to gather frames into our static buffer.
146
+ int frame_count = ddtrace_rb_profile_frames(
147
+ current_thread,
148
+ 0,
149
+ RUNTIME_STACK_MAX_FRAMES,
150
+ runtime_stack_buffer
151
+ );
152
+
153
+ if (frame_count <= 0) {
154
+ emit_placeholder_frame(emit_frame, "<runtime stack not found>");
155
+ return;
156
+ }
157
+
158
+ for (int i = frame_count - 1; i >= 0; i--) {
159
+ frame_info *info = &runtime_stack_buffer[i];
160
+
161
+ if (info->is_ruby_frame) {
162
+ const void *iseq = (const void *)info->as.ruby_frame.iseq;
163
+ ddog_CharSlice function_slice = DDOG_CHARSLICE_C("<unknown>");
164
+ ddog_CharSlice file_slice = DDOG_CHARSLICE_C("<unknown>");
165
+
166
+ if (iseq && is_pointer_readable(iseq, sizeof_rb_iseq_t())) {
167
+ function_slice = safe_string_value(ddtrace_iseq_base_label(iseq));
168
+ file_slice = safe_string_value(ddtrace_iseq_path(iseq));
169
+ }
170
+
171
+ ddog_crasht_RuntimeStackFrame frame = {
172
+ .type_name = DDOG_CHARSLICE_C(""),
173
+ .function = function_slice,
174
+ .file = file_slice,
175
+ .line = info->as.ruby_frame.line,
176
+ .column = 0
177
+ };
178
+
179
+ emit_frame(&frame);
180
+ } else {
181
+ ddog_CharSlice function_slice = DDOG_CHARSLICE_C("<C method>");
182
+ ddog_CharSlice file_slice = DDOG_CHARSLICE_C("<C extension>");
183
+
184
+ if (info->as.native_frame.method_id) {
185
+ const char *method_name = rb_id2name(info->as.native_frame.method_id);
186
+ if (is_pointer_readable(method_name, 256)) {
187
+ size_t method_name_len = strnlen(method_name, 256);
188
+ if (method_name_len > 0 && method_name_len < 256) {
189
+ function_slice = char_slice_from_cstr(method_name);
190
+ }
191
+ }
192
+ }
193
+
194
+ ddog_crasht_RuntimeStackFrame frame = {
195
+ .type_name = DDOG_CHARSLICE_C(""),
196
+ .function = function_slice,
197
+ .file = file_slice,
198
+ .line = 0,
199
+ .column = 0
200
+ };
201
+
202
+ emit_frame(&frame);
203
+ }
204
+ }
205
+
206
+ if (frame_count == RUNTIME_STACK_MAX_FRAMES) {
207
+ emit_placeholder_frame(emit_frame, "<truncated frames>");
208
+ }
209
+ }
210
+
211
+ void crashtracking_runtime_stacks_init(void) {
212
+ cached_page_size = (uintptr_t)sysconf(_SC_PAGESIZE);
213
+ if (cached_page_size == 0 || (cached_page_size & (cached_page_size - 1u))) {
214
+ cached_page_size = 4096;
215
+ }
216
+
217
+ if (crashtracker_thread_data_type == NULL) {
218
+ VALUE current_thread = rb_thread_current();
219
+ if (current_thread == Qnil) {
220
+ rb_raise(rb_eRuntimeError, "crashtracking_runtime_stacks_init: rb_thread_current returned Qnil");
221
+ }
222
+
223
+ const rb_data_type_t *thread_data_type = RTYPEDDATA_TYPE(current_thread);
224
+ if (!thread_data_type) {
225
+ rb_raise(rb_eRuntimeError, "crashtracking_runtime_stacks_init: RTYPEDDATA_TYPE returned NULL");
226
+ }
227
+
228
+ crashtracker_thread_data_type = thread_data_type;
229
+ }
230
+
231
+ // Register immediately so Ruby doesn't need to manage this explicitly.
232
+ ddog_crasht_register_runtime_frame_callback(ruby_runtime_stack_callback);
233
+ }
234
+
235
+ #else
236
+ // Keep init symbol to satisfy linkage on non linux platforms, but do nothing
237
+ void crashtracking_runtime_stacks_init(void) {}
238
+ #endif
239
+
@@ -3,7 +3,7 @@
3
3
  // IMPORTANT: Currently this file is copy-pasted between extensions. Make sure to update all versions when doing any change!
4
4
 
5
5
  #include <ruby.h>
6
- #include <datadog/profiling.h>
6
+ #include <datadog/common.h>
7
7
 
8
8
  // Used to mark symbols to be exported to the outside of the extension.
9
9
  // Consider very carefully before tagging a function with this.
@@ -138,11 +138,16 @@ if have_header("dlfcn.h")
138
138
  have_func("dladdr")
139
139
  end
140
140
 
141
- # On Ruby 3.5, we can't ask the object_id from IMEMOs (https://github.com/ruby/ruby/pull/13347)
142
- $defs << "-DNO_IMEMO_OBJECT_ID" unless RUBY_VERSION < "3.5"
141
+ # On older Rubies, there was no primitive mutex and condition variable implemented in `thread_sync.rb` (internal)
142
+ $defs << "-DNO_PRIMITIVE_MUTEX_AND_CONDITION_VARIABLE" if RUBY_VERSION < "4"
143
143
 
144
- # On Ruby 2.5 and 3.3, this symbol was not visible. It is on 2.6 to 3.2, as well as 3.4+
145
- $defs << "-DNO_RB_OBJ_INFO" if RUBY_VERSION.start_with?("2.5", "3.3")
144
+ # On Ruby 4, we can't ask the object_id from IMEMOs (https://github.com/ruby/ruby/pull/13347)
145
+ $defs << "-DNO_IMEMO_OBJECT_ID" unless RUBY_VERSION < "4"
146
+
147
+ # This symbol is exclusively visible on certain Ruby versions: 2.6 to 3.2, as well as 3.4 (but not 4.0+)
148
+ # It's only used to get extra information about an object when a failure happens, so it's a "very nice to have" but not
149
+ # actually required for correct behavior of the profiler.
150
+ $defs << "-DNO_RB_OBJ_INFO" if RUBY_VERSION.start_with?("2.5", "3.3", "4.")
146
151
 
147
152
  # On older Rubies, rb_postponed_job_preregister/rb_postponed_job_trigger did not exist
148
153
  $defs << "-DNO_POSTPONED_TRIGGER" if RUBY_VERSION < "3.3"
@@ -305,7 +305,7 @@ void start_heap_allocation_recording(heap_recorder *heap_recorder, VALUE new_obj
305
305
 
306
306
  if (++heap_recorder->num_recordings_skipped < heap_recorder->sample_rate ||
307
307
  #ifdef NO_IMEMO_OBJECT_ID
308
- // On Ruby 3.5, we can't ask the object_id from IMEMOs (https://github.com/ruby/ruby/pull/13347)
308
+ // On Ruby 4, we can't ask the object_id from IMEMOs (https://github.com/ruby/ruby/pull/13347)
309
309
  RB_BUILTIN_TYPE(new_obj) == RUBY_T_IMEMO
310
310
  #else
311
311
  false
@@ -76,6 +76,18 @@ rb_nativethread_id_t pthread_id_for(VALUE thread) {
76
76
  #endif
77
77
  }
78
78
 
79
+ size_t sizeof_rb_iseq_t(void) {
80
+ return sizeof(rb_iseq_t);
81
+ }
82
+
83
+ VALUE ddtrace_iseq_base_label(const void *iseq) {
84
+ return rb_iseq_base_label((const rb_iseq_t *)iseq);
85
+ }
86
+
87
+ VALUE ddtrace_iseq_path(const void *iseq) {
88
+ return rb_iseq_path((const rb_iseq_t *)iseq);
89
+ }
90
+
79
91
  // Queries if the current thread is the owner of the global VM lock.
80
92
  //
81
93
  // @ivoanjo: Ruby has a similarly-named `ruby_thread_has_gvl_p` but that API is insufficient for our needs because it can
@@ -47,6 +47,10 @@ VALUE thread_name_for(VALUE thread);
47
47
 
48
48
  int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, frame_info *stack_buffer);
49
49
 
50
+ size_t sizeof_rb_iseq_t(void);
51
+ VALUE ddtrace_iseq_base_label(const void *iseq);
52
+ VALUE ddtrace_iseq_path(const void *iseq);
53
+
50
54
  // Returns true if the current thread belongs to the main Ractor or if Ruby has no Ractor support
51
55
  bool ddtrace_rb_ractor_main_p(void);
52
56
 
@@ -23,6 +23,7 @@ void collectors_thread_context_init(VALUE profiling_module);
23
23
  void encoded_profile_init(VALUE profiling_module);
24
24
  void http_transport_init(VALUE profiling_module);
25
25
  void stack_recorder_init(VALUE profiling_module);
26
+ void crashtracking_runtime_stacks_init(void);
26
27
 
27
28
  static VALUE native_working_p(VALUE self);
28
29
  static VALUE _native_grab_gvl_and_raise(DDTRACE_UNUSED VALUE _self, VALUE exception_class, VALUE test_message, VALUE test_message_arg, VALUE release_gvl);
@@ -65,6 +66,7 @@ void DDTRACE_EXPORT Init_datadog_profiling_native_extension(void) {
65
66
  encoded_profile_init(profiling_module);
66
67
  http_transport_init(profiling_module);
67
68
  stack_recorder_init(profiling_module);
69
+ crashtracking_runtime_stacks_init();
68
70
  unsafe_api_calls_check_init();
69
71
 
70
72
  // Hosts methods used for testing the native code using RSpec
@@ -3,7 +3,7 @@
3
3
  // IMPORTANT: Currently this file is copy-pasted between extensions. Make sure to update all versions when doing any change!
4
4
 
5
5
  #include <ruby.h>
6
- #include <datadog/profiling.h>
6
+ #include <datadog/common.h>
7
7
 
8
8
  // Used to mark symbols to be exported to the outside of the extension.
9
9
  // Consider very carefully before tagging a function with this.