datadog 2.1.0 → 2.3.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 (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +101 -1
  3. data/ext/datadog_profiling_loader/extconf.rb +15 -15
  4. data/ext/datadog_profiling_native_extension/clock_id.h +1 -0
  5. data/ext/datadog_profiling_native_extension/clock_id_from_pthread.c +1 -2
  6. data/ext/datadog_profiling_native_extension/clock_id_noop.c +1 -2
  7. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +132 -44
  8. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +49 -26
  9. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +34 -4
  10. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +4 -0
  11. data/ext/datadog_profiling_native_extension/collectors_stack.c +90 -37
  12. data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -2
  13. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +81 -19
  14. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
  15. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +110 -0
  16. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +57 -0
  17. data/ext/datadog_profiling_native_extension/extconf.rb +69 -62
  18. data/ext/datadog_profiling_native_extension/heap_recorder.c +34 -6
  19. data/ext/datadog_profiling_native_extension/heap_recorder.h +3 -1
  20. data/ext/datadog_profiling_native_extension/helpers.h +6 -17
  21. data/ext/datadog_profiling_native_extension/http_transport.c +3 -3
  22. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +0 -86
  23. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +2 -23
  24. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +61 -126
  25. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +64 -138
  26. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +17 -11
  27. data/ext/datadog_profiling_native_extension/profiling.c +0 -2
  28. data/ext/datadog_profiling_native_extension/ruby_helpers.c +0 -33
  29. data/ext/datadog_profiling_native_extension/ruby_helpers.h +1 -26
  30. data/ext/datadog_profiling_native_extension/setup_signal_handler.c +1 -1
  31. data/ext/datadog_profiling_native_extension/setup_signal_handler.h +1 -0
  32. data/ext/datadog_profiling_native_extension/stack_recorder.c +27 -8
  33. data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -0
  34. data/ext/datadog_profiling_native_extension/time_helpers.c +0 -15
  35. data/ext/datadog_profiling_native_extension/time_helpers.h +36 -6
  36. data/ext/{datadog_profiling_native_extension → libdatadog_api}/crashtracker.c +20 -7
  37. data/ext/libdatadog_api/datadog_ruby_common.c +110 -0
  38. data/ext/libdatadog_api/datadog_ruby_common.h +57 -0
  39. data/ext/libdatadog_api/extconf.rb +108 -0
  40. data/ext/libdatadog_api/macos_development.md +26 -0
  41. data/ext/libdatadog_extconf_helpers.rb +130 -0
  42. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +49 -0
  43. data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +73 -0
  44. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +68 -0
  45. data/lib/datadog/appsec/contrib/graphql/integration.rb +41 -0
  46. data/lib/datadog/appsec/contrib/graphql/patcher.rb +37 -0
  47. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +59 -0
  48. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +1 -1
  49. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +1 -1
  50. data/lib/datadog/appsec/extensions.rb +1 -0
  51. data/lib/datadog/appsec/processor/actions.rb +1 -1
  52. data/lib/datadog/appsec/response.rb +15 -1
  53. data/lib/datadog/appsec.rb +1 -0
  54. data/lib/datadog/core/configuration/components.rb +17 -12
  55. data/lib/datadog/core/configuration/settings.rb +93 -7
  56. data/lib/datadog/core/configuration.rb +3 -17
  57. data/lib/datadog/core/crashtracking/agent_base_url.rb +21 -0
  58. data/lib/datadog/core/crashtracking/component.rb +111 -0
  59. data/lib/datadog/core/crashtracking/tag_builder.rb +39 -0
  60. data/lib/datadog/core/deprecations.rb +58 -0
  61. data/lib/datadog/core/diagnostics/environment_logger.rb +8 -11
  62. data/lib/datadog/core/environment/yjit.rb +5 -0
  63. data/lib/datadog/core/runtime/ext.rb +1 -0
  64. data/lib/datadog/core/runtime/metrics.rb +6 -0
  65. data/lib/datadog/core/telemetry/component.rb +154 -0
  66. data/lib/datadog/core/telemetry/emitter.rb +9 -11
  67. data/lib/datadog/core/telemetry/event.rb +132 -26
  68. data/lib/datadog/core/telemetry/ext.rb +3 -0
  69. data/lib/datadog/core/telemetry/http/adapters/net.rb +11 -13
  70. data/lib/datadog/core/telemetry/http/ext.rb +3 -0
  71. data/lib/datadog/core/telemetry/http/transport.rb +38 -9
  72. data/lib/datadog/core/telemetry/logging.rb +35 -0
  73. data/lib/datadog/core/telemetry/metric.rb +167 -0
  74. data/lib/datadog/core/telemetry/metrics_collection.rb +81 -0
  75. data/lib/datadog/core/telemetry/metrics_manager.rb +81 -0
  76. data/lib/datadog/core/telemetry/request.rb +1 -1
  77. data/lib/datadog/core/telemetry/worker.rb +173 -0
  78. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +102 -0
  79. data/lib/datadog/core/utils/only_once_successful.rb +76 -0
  80. data/lib/datadog/core.rb +2 -19
  81. data/lib/datadog/kit/appsec/events.rb +2 -4
  82. data/lib/datadog/opentelemetry/sdk/propagator.rb +5 -10
  83. data/lib/datadog/opentelemetry/sdk/span_processor.rb +15 -2
  84. data/lib/datadog/opentelemetry/sdk/trace/span.rb +23 -0
  85. data/lib/datadog/profiling/collectors/code_provenance.rb +24 -11
  86. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +17 -17
  87. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +11 -13
  88. data/lib/datadog/profiling/collectors/info.rb +3 -3
  89. data/lib/datadog/profiling/collectors/thread_context.rb +4 -2
  90. data/lib/datadog/profiling/component.rb +85 -90
  91. data/lib/datadog/profiling/exporter.rb +3 -3
  92. data/lib/datadog/profiling/ext/dir_monkey_patches.rb +410 -0
  93. data/lib/datadog/profiling/ext.rb +21 -21
  94. data/lib/datadog/profiling/flush.rb +1 -1
  95. data/lib/datadog/profiling/http_transport.rb +8 -6
  96. data/lib/datadog/profiling/load_native_extension.rb +5 -5
  97. data/lib/datadog/profiling/preload.rb +1 -1
  98. data/lib/datadog/profiling/profiler.rb +5 -8
  99. data/lib/datadog/profiling/scheduler.rb +31 -25
  100. data/lib/datadog/profiling/tag_builder.rb +2 -2
  101. data/lib/datadog/profiling/tasks/exec.rb +5 -5
  102. data/lib/datadog/profiling/tasks/setup.rb +16 -35
  103. data/lib/datadog/profiling.rb +5 -5
  104. data/lib/datadog/tracing/contrib/action_cable/event.rb +1 -1
  105. data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +1 -1
  106. data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +1 -1
  107. data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +1 -1
  108. data/lib/datadog/tracing/contrib/action_mailer/event.rb +4 -6
  109. data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +9 -4
  110. data/lib/datadog/tracing/contrib/action_mailer/events/process.rb +3 -2
  111. data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +1 -5
  112. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +1 -1
  113. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +1 -1
  114. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +1 -1
  115. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +1 -1
  116. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +1 -1
  117. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +1 -1
  118. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +1 -1
  119. data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
  120. data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +1 -1
  121. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
  122. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +2 -1
  123. data/lib/datadog/tracing/contrib/active_support/cache/event.rb +32 -0
  124. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +156 -0
  125. data/lib/datadog/tracing/contrib/active_support/cache/events.rb +34 -0
  126. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +45 -41
  127. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +17 -40
  128. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +4 -1
  129. data/lib/datadog/tracing/contrib/active_support/notifications/event.rb +29 -6
  130. data/lib/datadog/tracing/contrib/active_support/notifications/subscriber.rb +16 -4
  131. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +33 -29
  132. data/lib/datadog/tracing/contrib/analytics.rb +5 -0
  133. data/lib/datadog/tracing/contrib/ext.rb +14 -0
  134. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +5 -0
  135. data/lib/datadog/tracing/contrib/graphql/patcher.rb +8 -2
  136. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +166 -0
  137. data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +28 -0
  138. data/lib/datadog/tracing/contrib/kafka/consumer_event.rb +1 -1
  139. data/lib/datadog/tracing/contrib/kafka/consumer_group_event.rb +1 -1
  140. data/lib/datadog/tracing/contrib/kafka/event.rb +1 -1
  141. data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +3 -3
  142. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +3 -3
  143. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +3 -3
  144. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +3 -3
  145. data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +3 -3
  146. data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +3 -3
  147. data/lib/datadog/tracing/contrib/lograge/patcher.rb +16 -0
  148. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +5 -0
  149. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +17 -13
  150. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +5 -0
  151. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +4 -1
  152. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +28 -0
  153. data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +5 -1
  154. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +22 -10
  155. data/lib/datadog/tracing/contrib/racecar/event.rb +2 -2
  156. data/lib/datadog/tracing/contrib/rails/ext.rb +9 -0
  157. data/lib/datadog/tracing/contrib/rails/patcher.rb +7 -0
  158. data/lib/datadog/tracing/contrib/rails/runner.rb +95 -0
  159. data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +5 -0
  160. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +4 -1
  161. data/lib/datadog/tracing/diagnostics/environment_logger.rb +14 -16
  162. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  163. data/lib/datadog/tracing/distributed/b3_single.rb +3 -1
  164. data/lib/datadog/tracing/distributed/datadog.rb +2 -2
  165. data/lib/datadog/tracing/distributed/propagation.rb +9 -2
  166. data/lib/datadog/tracing/distributed/trace_context.rb +3 -2
  167. data/lib/datadog/tracing/metadata/errors.rb +9 -1
  168. data/lib/datadog/tracing/metadata/ext.rb +4 -0
  169. data/lib/datadog/tracing/pipeline/span_filter.rb +2 -2
  170. data/lib/datadog/tracing/span.rb +9 -2
  171. data/lib/datadog/tracing/span_event.rb +41 -0
  172. data/lib/datadog/tracing/span_operation.rb +9 -4
  173. data/lib/datadog/tracing/trace_operation.rb +7 -3
  174. data/lib/datadog/tracing/trace_segment.rb +4 -1
  175. data/lib/datadog/tracing/tracer.rb +9 -2
  176. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -0
  177. data/lib/datadog/tracing.rb +5 -1
  178. data/lib/datadog/version.rb +2 -2
  179. metadata +43 -12
  180. data/lib/datadog/core/telemetry/client.rb +0 -95
  181. data/lib/datadog/core/telemetry/heartbeat.rb +0 -33
  182. data/lib/datadog/profiling/crashtracker.rb +0 -91
  183. data/lib/datadog/profiling/ext/forking.rb +0 -98
@@ -1,77 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rubygems'
4
- require 'pathname'
5
-
6
3
  module Datadog
7
4
  module Profiling
8
5
  # Helpers for extconf.rb
9
6
  module NativeExtensionHelpers
10
7
  # Can be set when customers want to skip compiling the native extension entirely
11
- ENV_NO_EXTENSION = 'DD_PROFILING_NO_EXTENSION'
8
+ ENV_NO_EXTENSION = "DD_PROFILING_NO_EXTENSION"
12
9
  # Can be set to force rubygems to fail gem installation when profiling extension could not be built
13
- ENV_FAIL_INSTALL_IF_MISSING_EXTENSION = 'DD_PROFILING_FAIL_INSTALL_IF_MISSING_EXTENSION'
10
+ ENV_FAIL_INSTALL_IF_MISSING_EXTENSION = "DD_PROFILING_FAIL_INSTALL_IF_MISSING_EXTENSION"
14
11
 
15
12
  # The MJIT header was introduced on 2.6 and removed on 3.3; for other Rubies we rely on debase-ruby_core_source
16
- CAN_USE_MJIT_HEADER = RUBY_VERSION.start_with?('2.6', '2.7', '3.0.', '3.1.', '3.2.')
17
-
18
- LIBDATADOG_VERSION = '~> 9.0.0.1.0'
13
+ CAN_USE_MJIT_HEADER = RUBY_VERSION.start_with?("2.6", "2.7", "3.0.", "3.1.", "3.2.")
19
14
 
20
15
  def self.fail_install_if_missing_extension?
21
- ENV[ENV_FAIL_INSTALL_IF_MISSING_EXTENSION].to_s.strip.downcase == 'true'
22
- end
23
-
24
- # Used as an workaround for a limitation with how dynamic linking works in environments where the datadog gem and
25
- # libdatadog are moved after the extension gets compiled.
26
- #
27
- # Because the libddpprof native library is installed on a non-standard system path, in order for it to be
28
- # found by the system dynamic linker (e.g. what takes care of dlopen(), which is used to load the profiling
29
- # native extension), we need to add a "runpath" -- a list of folders to search for libdatadog.
30
- #
31
- # This runpath gets hardcoded at native library linking time. You can look at it using the `readelf` tool in
32
- # Linux: e.g. `readelf -d datadog_profiling_native_extension.2.7.3_x86_64-linux.so`.
33
- #
34
- # In older versions of the datadog gem, we only set as runpath an absolute path to libdatadog.
35
- # (This gets set automatically by the call
36
- # to `pkg_config('datadog_profiling_with_rpath')` in `extconf.rb`). This worked fine as long as libdatadog was **NOT**
37
- # moved from the folder it was present at datadog gem installation/linking time.
38
- #
39
- # Unfortunately, environments such as Heroku and AWS Elastic Beanstalk move gems around in the filesystem after
40
- # installation. Thus, the profiling native extension could not be loaded in these environments
41
- # (see https://github.com/DataDog/dd-trace-rb/issues/2067) because libdatadog could not be found.
42
- #
43
- # To workaround this issue, this method computes the **relative** path between the folder where the profiling
44
- # native extension is going to be installed and the folder where libdatadog is installed, and returns it
45
- # to be set as an additional runpath. (Yes, you can set multiple runpath folders to be searched).
46
- #
47
- # This way, if both gems are moved together (and it turns out that they are in these environments),
48
- # the relative path can still be traversed to find libdatadog.
49
- #
50
- # This is incredibly awful, and it's kinda bizarre how it's not possible to just find these paths at runtime
51
- # and set them correctly; rather than needing to set stuff at linking-time and then praying to $deity that
52
- # weird moves don't happen.
53
- #
54
- # As a curiosity, `LD_LIBRARY_PATH` can be used to influence the folders that get searched but **CANNOT BE
55
- # SET DYNAMICALLY**, e.g. it needs to be set at the start of the process (Ruby VM) and thus it's not something
56
- # we could setup when doing a `require`.
57
- #
58
- def self.libdatadog_folder_relative_to_native_lib_folder(
59
- current_folder: __dir__,
60
- libdatadog_pkgconfig_folder: Libdatadog.pkgconfig_folder
61
- )
62
- return unless libdatadog_pkgconfig_folder
63
-
64
- profiling_native_lib_folder = "#{current_folder}/../../lib/"
65
- libdatadog_lib_folder = "#{libdatadog_pkgconfig_folder}/../"
66
-
67
- Pathname.new(libdatadog_lib_folder).relative_path_from(Pathname.new(profiling_native_lib_folder)).to_s
16
+ ENV[ENV_FAIL_INSTALL_IF_MISSING_EXTENSION].to_s.strip.downcase == "true"
68
17
  end
69
18
 
70
19
  # Used to check if profiler is supported, including user-visible clear messages explaining why their
71
20
  # system may not be supported.
72
21
  module Supported
73
22
  private_class_method def self.explain_issue(*reason, suggested:)
74
- { reason: reason, suggested: suggested }
23
+ {reason: reason, suggested: suggested}
75
24
  end
76
25
 
77
26
  def self.supported?
@@ -97,16 +46,16 @@ module Datadog
97
46
  outcome =
98
47
  if fail_install
99
48
  [
100
- 'Failing installation immediately because the ',
49
+ "Failing installation immediately because the ",
101
50
  "`#{ENV_FAIL_INSTALL_IF_MISSING_EXTENSION}` environment variable is set",
102
- 'to `true`.',
103
- 'When contacting support, please include the <mkmf.log> file that is shown ',
104
- 'below.',
51
+ "to `true`.",
52
+ "When contacting support, please include the <mkmf.log> file that is shown ",
53
+ "below.",
105
54
  ]
106
55
  else
107
56
  [
108
- 'The Datadog Continuous Profiler will not be available,',
109
- 'but all other datadog features will work fine!',
57
+ "The Datadog Continuous Profiler will not be available,",
58
+ "but all other datadog features will work fine!",
110
59
  ]
111
60
  end
112
61
 
@@ -124,22 +73,14 @@ module Datadog
124
73
 
125
74
  # This will be saved in a file to later be presented while operating the gem
126
75
  def self.render_skipped_reason_file(reason:, suggested:)
127
- [*reason, *suggested].join(' ')
128
- end
129
-
130
- # mkmf sets $PKGCONFIG after the `pkg_config` gets used in extconf.rb. When `pkg_config` is unsuccessful, we use
131
- # this helper to decide if we can show more specific error message vs a generic "something went wrong".
132
- def self.pkg_config_missing?(command: $PKGCONFIG) # rubocop:disable Style/GlobalVars
133
- pkg_config_available = command && xsystem("#{command} --version")
134
-
135
- pkg_config_available != true
76
+ [*reason, *suggested].join(" ")
136
77
  end
137
78
 
138
79
  CONTACT_SUPPORT = [
139
- 'For help solving this issue, please contact Datadog support at',
140
- '<https://docs.datadoghq.com/help/>.',
141
- 'You can also check out the Continuous Profiler troubleshooting page at',
142
- '<https://dtdg.co/ruby-profiler-troubleshooting>.'
80
+ "For help solving this issue, please contact Datadog support at",
81
+ "<https://docs.datadoghq.com/help/>.",
82
+ "You can also check out the Continuous Profiler troubleshooting page at",
83
+ "<https://dtdg.co/ruby-profiler-troubleshooting>."
143
84
  ].freeze
144
85
 
145
86
  GET_IN_TOUCH = [
@@ -147,83 +88,83 @@ module Datadog
147
88
  ].freeze
148
89
 
149
90
  UPGRADE_RUBY = [
150
- 'Upgrade to a modern Ruby to enable profiling for your app.'
91
+ "Upgrade to a modern Ruby to enable profiling for your app."
151
92
  ].freeze
152
93
 
153
94
  # Validation for this check is done in extconf.rb because it relies on mkmf
154
95
  FAILED_TO_CONFIGURE_LIBDATADOG = explain_issue(
155
- 'there was a problem in setting up the `libdatadog` dependency.',
96
+ "there was a problem in setting up the `libdatadog` dependency.",
156
97
  suggested: CONTACT_SUPPORT,
157
98
  )
158
99
 
159
100
  # Validation for this check is done in extconf.rb because it relies on mkmf
160
101
  COMPILATION_BROKEN = explain_issue(
161
- 'compilation of the Ruby VM just-in-time header failed.',
162
- 'Your C compiler or Ruby VM just-in-time compiler seem to be broken.',
102
+ "compilation of the Ruby VM just-in-time header failed.",
103
+ "Your C compiler or Ruby VM just-in-time compiler seem to be broken.",
163
104
  suggested: CONTACT_SUPPORT,
164
105
  )
165
106
 
166
107
  # Validation for this check is done in extconf.rb because it relies on mkmf
167
108
  PKG_CONFIG_IS_MISSING = explain_issue(
168
109
  # ----------------------------------------------------------------------------+
169
- 'the `pkg-config` system tool is missing.',
170
- 'This issue can usually be fixed by installing one of the following:',
171
- 'the `pkg-config` package on Homebrew and Debian/Ubuntu-based Linux;',
172
- 'the `pkgconf` package on Arch and Alpine-based Linux;',
173
- 'the `pkgconf-pkg-config` package on Fedora/Red Hat-based Linux.',
174
- '(Tip: When fixing this, ensure `pkg-config` is installed **before**',
175
- 'running `bundle install`, and remember to clear any installed gems cache).',
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).",
176
117
  suggested: CONTACT_SUPPORT,
177
118
  )
178
119
 
179
120
  # Validation for this check is done in extconf.rb because it relies on mkmf
180
121
  COMPILER_ATOMIC_MISSING = explain_issue(
181
- 'your C compiler is missing support for the <stdatomic.h> header.',
182
- 'This issue can usually be fixed by upgrading to a later version of your',
183
- 'operating system image or compiler.',
122
+ "your C compiler is missing support for the <stdatomic.h> header.",
123
+ "This issue can usually be fixed by upgrading to a later version of your",
124
+ "operating system image or compiler.",
184
125
  suggested: CONTACT_SUPPORT,
185
126
  )
186
127
 
187
128
  private_class_method def self.disabled_via_env?
188
129
  report_disabled = [
189
- 'If you needed to use this, please tell us why on',
190
- '<https://github.com/DataDog/dd-trace-rb/issues/new> so we can fix it :)',
130
+ "If you needed to use this, please tell us why on",
131
+ "<https://github.com/DataDog/dd-trace-rb/issues/new> so we can fix it :)",
191
132
  ].freeze
192
133
 
193
134
  disabled_via_env = explain_issue(
194
- 'the `DD_PROFILING_NO_EXTENSION` environment variable is/was set to',
195
- '`true` during installation.',
135
+ "the `DD_PROFILING_NO_EXTENSION` environment variable is/was set to",
136
+ "`true` during installation.",
196
137
  suggested: report_disabled,
197
138
  )
198
139
 
199
- return unless ENV[ENV_NO_EXTENSION].to_s.strip.downcase == 'true'
140
+ return unless ENV[ENV_NO_EXTENSION].to_s.strip.downcase == "true"
200
141
 
201
142
  disabled_via_env
202
143
  end
203
144
 
204
145
  private_class_method def self.on_jruby?
205
146
  jruby_not_supported = explain_issue(
206
- 'JRuby is not supported by the Datadog Continuous Profiler.',
147
+ "JRuby is not supported by the Datadog Continuous Profiler.",
207
148
  suggested: GET_IN_TOUCH,
208
149
  )
209
150
 
210
- jruby_not_supported if RUBY_ENGINE == 'jruby'
151
+ jruby_not_supported if RUBY_ENGINE == "jruby"
211
152
  end
212
153
 
213
154
  private_class_method def self.on_truffleruby?
214
155
  truffleruby_not_supported = explain_issue(
215
- 'TruffleRuby is not supported by the datadog gem.',
156
+ "TruffleRuby is not supported by the datadog gem.",
216
157
  suggested: GET_IN_TOUCH,
217
158
  )
218
159
 
219
- truffleruby_not_supported if RUBY_ENGINE == 'truffleruby'
160
+ truffleruby_not_supported if RUBY_ENGINE == "truffleruby"
220
161
  end
221
162
 
222
163
  # See https://docs.datadoghq.com/tracing/setup_overview/setup/ruby/#microsoft-windows-support for current
223
164
  # state of Windows support in the datadog gem.
224
165
  private_class_method def self.on_windows?
225
166
  windows_not_supported = explain_issue(
226
- 'Microsoft Windows is not supported by the Datadog Continuous Profiler.',
167
+ "Microsoft Windows is not supported by the Datadog Continuous Profiler.",
227
168
  suggested: GET_IN_TOUCH,
228
169
  )
229
170
 
@@ -232,72 +173,66 @@ module Datadog
232
173
 
233
174
  private_class_method def self.on_macos?
234
175
  macos_not_supported = explain_issue(
235
- 'macOS is currently not supported by the Datadog Continuous Profiler.',
176
+ "macOS is currently not supported by the Datadog Continuous Profiler.",
236
177
  suggested: GET_IN_TOUCH,
237
178
  )
238
179
  # For development only; not supported otherwise
239
- macos_testing_override = ENV['DD_PROFILING_MACOS_TESTING'] == 'true'
180
+ macos_testing_override = ENV["DD_PROFILING_MACOS_TESTING"] == "true"
240
181
 
241
- macos_not_supported if RUBY_PLATFORM.include?('darwin') && !macos_testing_override
182
+ macos_not_supported if RUBY_PLATFORM.include?("darwin") && !macos_testing_override
242
183
  end
243
184
 
244
185
  private_class_method def self.on_unknown_os?
245
186
  unknown_os_not_supported = explain_issue(
246
- 'your operating system is not supported by the Datadog Continuous Profiler.',
187
+ "your operating system is not supported by the Datadog Continuous Profiler.",
247
188
  suggested: GET_IN_TOUCH,
248
189
  )
249
190
 
250
- unknown_os_not_supported unless RUBY_PLATFORM.include?('darwin') || RUBY_PLATFORM.include?('linux')
191
+ unknown_os_not_supported unless RUBY_PLATFORM.include?("darwin") || RUBY_PLATFORM.include?("linux")
251
192
  end
252
193
 
253
194
  private_class_method def self.on_unsupported_cpu_arch?
254
195
  architecture_not_supported = explain_issue(
255
- 'your CPU architecture is not supported by the Datadog Continuous Profiler.',
196
+ "your CPU architecture is not supported by the Datadog Continuous Profiler.",
256
197
  suggested: GET_IN_TOUCH,
257
198
  )
258
199
 
259
- architecture_not_supported unless RUBY_PLATFORM.start_with?('x86_64', 'aarch64', 'arm64')
200
+ architecture_not_supported unless RUBY_PLATFORM.start_with?("x86_64", "aarch64", "arm64")
260
201
  end
261
202
 
262
203
  # On some Rubies, we require the mjit header to be present. If Ruby was installed without MJIT support, we also skip
263
204
  # building the extension.
264
205
  private_class_method def self.expected_to_use_mjit_but_mjit_is_disabled?
265
206
  ruby_without_mjit = explain_issue(
266
- 'your Ruby has been compiled without JIT support (--disable-jit-support).',
267
- 'The profiling native extension requires a Ruby compiled with JIT support,',
268
- 'even if the JIT is not in use by the application itself.',
207
+ "your Ruby has been compiled without JIT support (--disable-jit-support).",
208
+ "The profiling native extension requires a Ruby compiled with JIT support,",
209
+ "even if the JIT is not in use by the application itself.",
269
210
  suggested: CONTACT_SUPPORT,
270
211
  )
271
212
 
272
- ruby_without_mjit if CAN_USE_MJIT_HEADER && RbConfig::CONFIG['MJIT_SUPPORT'] != 'yes'
213
+ ruby_without_mjit if CAN_USE_MJIT_HEADER && RbConfig::CONFIG["MJIT_SUPPORT"] != "yes"
273
214
  end
274
215
 
275
216
  private_class_method def self.libdatadog_not_available?
276
- begin
277
- gem 'libdatadog', LIBDATADOG_VERSION
278
- require 'libdatadog'
279
- nil
280
- # rubocop:disable Lint/RescueException
281
- rescue Exception => e
217
+ Datadog::LibdatadogExtconfHelpers.try_loading_libdatadog do |exception|
282
218
  explain_issue(
283
- 'there was an exception during loading of the `libdatadog` gem:',
284
- e.class.name,
285
- *e.message.split("\n"),
286
- *Array(e.backtrace),
287
- '.',
219
+ "there was an exception during loading of the `libdatadog` gem:",
220
+ exception.class.name,
221
+ *exception.message.split("\n"),
222
+ *Array(exception.backtrace),
223
+ ".",
288
224
  suggested: CONTACT_SUPPORT,
289
225
  )
290
226
  end
291
- # rubocop:enable Lint/RescueException
292
227
  end
293
228
 
294
229
  private_class_method def self.libdatadog_not_usable?
295
230
  no_binaries_for_current_platform = explain_issue(
296
- 'the `libdatadog` gem installed on your system is missing binaries for your',
297
- 'platform variant.',
231
+ "the `libdatadog` gem installed on your system is missing binaries for your",
232
+ "platform variant.",
298
233
  "(Your platform: `#{Libdatadog.current_platform}`)",
299
- '(Available binaries:',
300
- "`#{Libdatadog.available_binaries.join('`, `')}`)",
234
+ "(Available binaries:",
235
+ "`#{Libdatadog.available_binaries.join("`, `")}`)",
301
236
  suggested: CONTACT_SUPPORT,
302
237
  )
303
238
 
@@ -311,7 +311,7 @@ VALUE thread_name_for(VALUE thread) {
311
311
  // with diagnostic stuff. See https://nelkinda.com/blog/suppress-warnings-in-gcc-and-clang/#d11e364 for details.
312
312
  #pragma GCC diagnostic push
313
313
  #pragma GCC diagnostic ignored "-Wunused-parameter"
314
- inline static int
314
+ static inline int
315
315
  calc_pos(const rb_iseq_t *iseq, const VALUE *pc, int *lineno, int *node_id)
316
316
  {
317
317
  VM_ASSERT(iseq);
@@ -364,7 +364,7 @@ calc_pos(const rb_iseq_t *iseq, const VALUE *pc, int *lineno, int *node_id)
364
364
  // Copyright (C) 1993-2012 Yukihiro Matsumoto
365
365
  // to support our custom rb_profile_frames (see below)
366
366
  // Modifications: None
367
- inline static int
367
+ static inline int
368
368
  calc_lineno(const rb_iseq_t *iseq, const VALUE *pc)
369
369
  {
370
370
  int lineno;
@@ -376,8 +376,8 @@ calc_lineno(const rb_iseq_t *iseq, const VALUE *pc)
376
376
  // Copyright (C) 1993-2012 Yukihiro Matsumoto
377
377
  // Modifications:
378
378
  // * Renamed rb_profile_frames => ddtrace_rb_profile_frames
379
- // * Add thread argument
380
- // * Add is_ruby_frame argument
379
+ // * Add thread argument (this is now upstream, actually!)
380
+ // * Add frame_flags.is_ruby_frame argument
381
381
  // * Removed `if (lines)` tests -- require/assume that like `buff`, `lines` is always specified
382
382
  // * Skip dummy frame that shows up in main thread
383
383
  // * Add `end_cfp == NULL` and `end_cfp <= cfp` safety checks. These are used in a bunch of places in
@@ -392,6 +392,9 @@ calc_lineno(const rb_iseq_t *iseq, const VALUE *pc)
392
392
  // was called from.
393
393
  // * Imported fix from https://github.com/ruby/ruby/pull/7116 to avoid sampling threads that are still being created
394
394
  // * Imported fix from https://github.com/ruby/ruby/pull/8415 to avoid potential crash when using YJIT.
395
+ // * Add frame_flags.same_frame and logic to skip redoing work if the buffer already contains the same data we're collecting
396
+ // * Skipped use of rb_callable_method_entry_t (cme) for Ruby frames as it doesn't impact us.
397
+ // * Imported fix from https://github.com/ruby/ruby/pull/8280 to keep us closer to upstream
395
398
  //
396
399
  // What is rb_profile_frames?
397
400
  // `rb_profile_frames` is a Ruby VM debug API added for use by profilers for sampling the stack trace of a Ruby thread.
@@ -421,8 +424,7 @@ calc_lineno(const rb_iseq_t *iseq, const VALUE *pc)
421
424
  // and friends). We've found quite a few situations where the data from rb_profile_frames and the reference APIs
422
425
  // disagree, and quite a few of them seem oversights/bugs (speculation from my part) rather than deliberate
423
426
  // decisions.
424
- int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, VALUE *buff, int *lines, bool* is_ruby_frame)
425
- {
427
+ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, frame_info *stack_buffer) {
426
428
  int i;
427
429
  // Modified from upstream: Instead of using `GET_EC` to collect info from the current thread,
428
430
  // support sampling any thread (including the current) passed as an argument
@@ -466,7 +468,7 @@ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, VALUE *buff, i
466
468
  // See comment on `record_placeholder_stack_in_native_code` for a full explanation of what this means (and why we don't just return 0)
467
469
  if (end_cfp <= cfp) return PLACEHOLDER_STACK_IN_NATIVE_CODE;
468
470
 
469
- for (i=0; i<limit && cfp != end_cfp;) {
471
+ for (i=0; i<limit && cfp != end_cfp; cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)) {
470
472
  if (cfp->iseq && !cfp->pc) {
471
473
  // Fix: Do nothing -- this frame should not be used
472
474
  //
@@ -479,164 +481,88 @@ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, VALUE *buff, i
479
481
  continue;
480
482
  }
481
483
 
482
- /* record frame info */
483
- cme = rb_vm_frame_method_entry(cfp);
484
+ stack_buffer[i].same_frame =
485
+ stack_buffer[i].is_ruby_frame &&
486
+ stack_buffer[i].as.ruby_frame.iseq == (VALUE) cfp->iseq &&
487
+ stack_buffer[i].as.ruby_frame.caching_pc == cfp->pc;
484
488
 
485
- if (cme && cme->def->type == VM_METHOD_TYPE_ISEQ &&
486
- // Fix: Do not use callable method entry when iseq is for an eval.
487
- // TL;DR: This fix is needed for us to match the Ruby reference API information in the
488
- // "when sampling an eval/instance eval inside an object" spec.
489
- //
490
- // Longer note:
491
- // When a frame is a ruby frame (VM_FRAME_RUBYFRAME_P above), we can get information about it
492
- // by introspecting both the callable method entry, as well as the iseq directly.
493
- // Often they match... but sometimes they provide different info (as in the "iseq for an eval" situation
494
- // here).
495
- // If my reading of vm_backtrace.c is correct, the actual Ruby stack trace API **never** uses the
496
- // callable method entry for Ruby frames, but only for VM_METHOD_TYPE_CFUNC (see `backtrace_each` method
497
- // on that file).
498
- // So... why does `rb_profile_frames` do something different? Is it a bug? Is it because it exposes
499
- // more information than the Ruby stack frame API?
500
- // As a final note, the `backtracie` gem (https://github.com/ivoanjo/backtracie) can be used to introspect
501
- // the full metadata provided by both the callable method entry as well as the iseq, and is really useful
502
- // to debug and learn more about these differences.
503
- cfp->iseq->body->type != ISEQ_TYPE_EVAL) {
504
- buff[i] = (VALUE)cme;
505
- }
506
- else {
507
- buff[i] = (VALUE)cfp->iseq;
489
+ if (stack_buffer[i].same_frame) { // Nothing to do, buffer already contains this frame
490
+ i++;
491
+ continue;
508
492
  }
509
493
 
494
+ // dd-trace-rb NOTE:
495
+ // Upstream Ruby has code here to retrieve the rb_callable_method_entry_t (cme) and in some cases to use it
496
+ // instead of the iseq.
497
+ // In practice, they are usually the same; the difference is that when you have e.g. block, one gets you a
498
+ // reference to the block, and the other to the method containing the block.
499
+ // This would be important if we used `rb_profile_frame_label` and wanted the "block in foo" label instead
500
+ // of just "foo". But we're currently using `rb_profile_frame_base_label` which I believe is always the same
501
+ // between the rb_callable_method_entry_t and the iseq. Thus, to simplify a bit our logic and reduce a bit
502
+ // the overhead, we always use the iseq here.
503
+ //
504
+ // @ivoanjo: I've left the upstream Ruby code commented out below for reference, so it's more obvious that
505
+ // we're diverging, and we can easily compare and experiment with the upstream version in the future.
506
+ //
507
+ // cme = rb_vm_frame_method_entry(cfp);
508
+
509
+ // if (cme && cme->def->type == VM_METHOD_TYPE_ISEQ &&
510
+ // // Fix: Do not use callable method entry when iseq is for an eval.
511
+ // // TL;DR: This fix is needed for us to match the Ruby reference API information in the
512
+ // // "when sampling an eval/instance eval inside an object" spec.
513
+ // cfp->iseq->body->type != ISEQ_TYPE_EVAL) {
514
+ // buff[i] = (VALUE)cme;
515
+ // }
516
+ // else {
517
+ stack_buffer[i].as.ruby_frame.iseq = (VALUE)cfp->iseq;
518
+ stack_buffer[i].as.ruby_frame.caching_pc = (void *) cfp->pc;
519
+ // }
520
+
510
521
  // The topmost frame may not have an updated PC because the JIT
511
522
  // may not have set one. The JIT compiler will update the PC
512
523
  // before entering a new function (so that `caller` will work),
513
524
  // so only the topmost frame could possibly have an out of date PC
514
525
  #ifndef NO_JIT_RETURN
515
526
  if (cfp == top && cfp->jit_return) {
516
- lines[i] = 0;
527
+ stack_buffer[i].as.ruby_frame.line = 0;
517
528
  } else {
518
- lines[i] = calc_lineno(cfp->iseq, cfp->pc);
529
+ stack_buffer[i].as.ruby_frame.line = calc_lineno(cfp->iseq, cfp->pc);
519
530
  }
520
531
  #else // Ruby < 3.1
521
- lines[i] = calc_lineno(cfp->iseq, cfp->pc);
532
+ stack_buffer[i].as.ruby_frame.line = calc_lineno(cfp->iseq, cfp->pc);
522
533
  #endif
523
534
 
524
- is_ruby_frame[i] = true;
535
+ stack_buffer[i].is_ruby_frame = true;
525
536
  i++;
526
537
  }
527
538
  else {
528
539
  cme = rb_vm_frame_method_entry(cfp);
529
540
  if (cme && cme->def->type == VM_METHOD_TYPE_CFUNC) {
530
- buff[i] = (VALUE)cme;
531
- lines[i] = 0;
532
- is_ruby_frame[i] = false;
541
+ if (start > 0) {
542
+ start--;
543
+ continue;
544
+ }
545
+
546
+ stack_buffer[i].same_frame =
547
+ !stack_buffer[i].is_ruby_frame &&
548
+ stack_buffer[i].as.native_frame.caching_cme == (VALUE) cme;
549
+
550
+ if (stack_buffer[i].same_frame) { // Nothing to do, buffer already contains this frame
551
+ i++;
552
+ continue;
553
+ }
554
+
555
+ stack_buffer[i].as.native_frame.caching_cme = (VALUE)cme;
556
+ stack_buffer[i].as.native_frame.method_id = cme->def->original_id;
557
+ stack_buffer[i].is_ruby_frame = false;
533
558
  i++;
534
559
  }
535
560
  }
536
- cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
537
561
  }
538
562
 
539
563
  return i;
540
564
  }
541
565
 
542
- #ifdef USE_BACKPORTED_RB_PROFILE_FRAME_METHOD_NAME
543
-
544
- // Taken from upstream vm_backtrace.c at commit 5f10bd634fb6ae8f74a4ea730176233b0ca96954 (March 2022, Ruby 3.2 trunk)
545
- // Copyright (C) 1993-2012 Yukihiro Matsumoto
546
- // to support our custom rb_profile_frame_method_name (see below)
547
- // Modifications: None
548
- static VALUE
549
- id2str(ID id)
550
- {
551
- VALUE str = rb_id2str(id);
552
- if (!str) return Qnil;
553
- return str;
554
- }
555
- #define rb_id2str(id) id2str(id)
556
-
557
- // Taken from upstream vm_backtrace.c at commit 5f10bd634fb6ae8f74a4ea730176233b0ca96954 (March 2022, Ruby 3.2 trunk)
558
- // Copyright (C) 1993-2012 Yukihiro Matsumoto
559
- // to support our custom rb_profile_frame_method_name (see below)
560
- // Modifications: None
561
- static const rb_iseq_t *
562
- frame2iseq(VALUE frame)
563
- {
564
- if (NIL_P(frame)) return NULL;
565
-
566
- if (RB_TYPE_P(frame, T_IMEMO)) {
567
- switch (imemo_type(frame)) {
568
- case imemo_iseq:
569
- return (const rb_iseq_t *)frame;
570
- case imemo_ment:
571
- {
572
- const rb_callable_method_entry_t *cme = (rb_callable_method_entry_t *)frame;
573
- switch (cme->def->type) {
574
- case VM_METHOD_TYPE_ISEQ:
575
- return cme->def->body.iseq.iseqptr;
576
- default:
577
- return NULL;
578
- }
579
- }
580
- default:
581
- break;
582
- }
583
- }
584
- rb_bug("frame2iseq: unreachable");
585
- }
586
-
587
- // Taken from upstream vm_backtrace.c at commit 5f10bd634fb6ae8f74a4ea730176233b0ca96954 (March 2022, Ruby 3.2 trunk)
588
- // Copyright (C) 1993-2012 Yukihiro Matsumoto
589
- // to support our custom rb_profile_frame_method_name (see below)
590
- // Modifications: None
591
- static const rb_callable_method_entry_t *
592
- cframe(VALUE frame)
593
- {
594
- if (NIL_P(frame)) return NULL;
595
-
596
- if (RB_TYPE_P(frame, T_IMEMO)) {
597
- switch (imemo_type(frame)) {
598
- case imemo_ment:
599
- {
600
- const rb_callable_method_entry_t *cme = (rb_callable_method_entry_t *)frame;
601
- switch (cme->def->type) {
602
- case VM_METHOD_TYPE_CFUNC:
603
- return cme;
604
- default:
605
- return NULL;
606
- }
607
- }
608
- default:
609
- return NULL;
610
- }
611
- }
612
-
613
- return NULL;
614
- }
615
-
616
- // Taken from upstream vm_backtrace.c at commit 5f10bd634fb6ae8f74a4ea730176233b0ca96954 (March 2022, Ruby 3.2 trunk)
617
- // Copyright (C) 1993-2012 Yukihiro Matsumoto
618
- //
619
- // Ruby 3.0 finally added support for showing CFUNC frames (frames for methods written using native code)
620
- // in stack traces gathered via `rb_profile_frames` (https://github.com/ruby/ruby/pull/3299).
621
- // To access this information on older Rubies, beyond using our custom `ddtrace_rb_profile_frames` above, we also need
622
- // to backport the Ruby 3.0+ version of `rb_profile_frame_method_name`.
623
- //
624
- // Modifications:
625
- // * Renamed rb_profile_frame_method_name => ddtrace_rb_profile_frame_method_name
626
- VALUE
627
- ddtrace_rb_profile_frame_method_name(VALUE frame)
628
- {
629
- const rb_callable_method_entry_t *cme = cframe(frame);
630
- if (cme) {
631
- ID mid = cme->def->original_id;
632
- return id2str(mid);
633
- }
634
- const rb_iseq_t *iseq = frame2iseq(frame);
635
- return iseq ? rb_iseq_method_name(iseq) : Qnil;
636
- }
637
-
638
- #endif // USE_BACKPORTED_RB_PROFILE_FRAME_METHOD_NAME
639
-
640
566
  // Support code for older Rubies that cannot use the MJIT header
641
567
  #ifndef RUBY_MJIT_HEADER
642
568
 
@@ -18,6 +18,22 @@ typedef struct {
18
18
  rb_nativethread_id_t owner;
19
19
  } current_gvl_owner;
20
20
 
21
+ typedef struct frame_info {
22
+ union {
23
+ struct {
24
+ VALUE iseq;
25
+ void *caching_pc; // For caching only
26
+ int line;
27
+ } ruby_frame;
28
+ struct {
29
+ VALUE caching_cme; // For caching only
30
+ ID method_id;
31
+ } native_frame;
32
+ } as;
33
+ bool is_ruby_frame : 1;
34
+ bool same_frame : 1;
35
+ } frame_info;
36
+
21
37
  rb_nativethread_id_t pthread_id_for(VALUE thread);
22
38
  bool is_current_thread_holding_the_gvl(void);
23
39
  current_gvl_owner gvl_owner(void);
@@ -27,20 +43,10 @@ void ddtrace_thread_list(VALUE result_array);
27
43
  bool is_thread_alive(VALUE thread);
28
44
  VALUE thread_name_for(VALUE thread);
29
45
 
30
- int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, VALUE *buff, int *lines, bool* is_ruby_frame);
46
+ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, frame_info *stack_buffer);
31
47
  // Returns true if the current thread belongs to the main Ractor or if Ruby has no Ractor support
32
48
  bool ddtrace_rb_ractor_main_p(void);
33
49
 
34
- // Ruby 3.0 finally added support for showing CFUNC frames (frames for methods written using native code)
35
- // in stack traces gathered via `rb_profile_frames` (https://github.com/ruby/ruby/pull/3299).
36
- // To access this information on older Rubies, beyond using our custom `ddtrace_rb_profile_frames` above, we also need
37
- // to backport the Ruby 3.0+ version of `rb_profile_frame_method_name`.
38
- #ifdef USE_BACKPORTED_RB_PROFILE_FRAME_METHOD_NAME
39
- VALUE ddtrace_rb_profile_frame_method_name(VALUE frame);
40
- #else // Ruby > 3.0, just use the stock functionality
41
- #define ddtrace_rb_profile_frame_method_name rb_profile_frame_method_name
42
- #endif
43
-
44
50
  // See comment on `record_placeholder_stack_in_native_code` for a full explanation of what this means (and why we don't just return 0)
45
51
  #define PLACEHOLDER_STACK_IN_NATIVE_CODE -1
46
52