From 40767413445ea7130762cf851ff2cde2b6330d82 Mon Sep 17 00:00:00 2001 From: Ivo Anjo Date: Tue, 25 Nov 2025 11:12:20 +0000 Subject: [PATCH] [PROF-13286] Disable heap profiling on Ruby 4 due to incompatibility **What does this PR do?** This PR disables the heap profiling feature when running on Ruby 4 as the current implementation (that relies on object_id) is not safe to use on Ruby 4. **Motivation:** Avoid impacting applications running on Ruby 4. **Additional Notes:** Discussion with the Ruby core team in https://bugs.ruby-lang.org/issues/21710 has uncovered that our use of object_id from inside the NEWOBJ tracepoint is not safe on Ruby 4, and it's likely it can't be made safe. Until we're able to replace the Datadog profiler's usage of object_id for heap profiling, we won't be able to safely offer this feature on Ruby 4. (We temporarily disabled the heap profiler for 4.0.0-preview2 in #5091 and re-enabled it in #5121 when it looked fixed but discussion on the upstream ticket uncovered further issues) **How to test the change?** Validate that profiler doesn't enable heap profiling on Ruby 4. --- lib/datadog/profiling/component.rb | 6 ++++++ .../collectors/cpu_and_wall_time_worker_spec.rb | 3 ++- spec/datadog/profiling/component_spec.rb | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/datadog/profiling/component.rb b/lib/datadog/profiling/component.rb index 0d31084f74..686824c9ed 100644 --- a/lib/datadog/profiling/component.rb +++ b/lib/datadog/profiling/component.rb @@ -220,6 +220,12 @@ def self.build_profiler_component(settings:, agent_settings:, optional_tracer:, "Please upgrade to Ruby >= 3.1 in order to use this feature. Heap profiling has been disabled." ) return false + elsif RUBY_VERSION.start_with?("4.") + logger.warn( + "Datadog Ruby heap profiler is currently incompatible with Ruby 4. " \ + "Heap profiling has been disabled." + ) + return false end unless allocation_profiling_enabled diff --git a/spec/datadog/profiling/collectors/cpu_and_wall_time_worker_spec.rb b/spec/datadog/profiling/collectors/cpu_and_wall_time_worker_spec.rb index 1d5d96578c..4f9983cb8d 100644 --- a/spec/datadog/profiling/collectors/cpu_and_wall_time_worker_spec.rb +++ b/spec/datadog/profiling/collectors/cpu_and_wall_time_worker_spec.rb @@ -865,7 +865,8 @@ before do skip "Heap profiling is only supported on Ruby >= 2.7" if RUBY_VERSION < "2.7" - skip "Heap profiling is buggy on 4.0.0preview2 (https://bugs.ruby-lang.org/issues/21710) but fixed in master" if RUBY_DESCRIPTION.include?("4.0.0preview2") + skip "Datadog Heap profiling is incompatible with Ruby 4, see https://bugs.ruby-lang.org/issues/21710 for discussion" if RUBY_VERSION.start_with?("4.") + allow(Datadog.logger).to receive(:warn) expect(Datadog.logger).to receive(:warn).with(/dynamic sampling rate disabled/) end diff --git a/spec/datadog/profiling/component_spec.rb b/spec/datadog/profiling/component_spec.rb index 15d97b7d7c..37a8201d62 100644 --- a/spec/datadog/profiling/component_spec.rb +++ b/spec/datadog/profiling/component_spec.rb @@ -334,6 +334,20 @@ end end + context "on Ruby 4.0 or newer" do + let(:testing_version) { "4.0.0" } + + it "initializes StackRecorder without heap sampling support and warns" do + expect(Datadog::Profiling::StackRecorder).to receive(:new) + .with(hash_including(heap_samples_enabled: false, heap_size_enabled: false)) + .and_call_original + + expect(logger).to receive(:warn).with(/Datadog Ruby heap profiler is currently incompatible with Ruby 4/) + + build_profiler_component + end + end + context "and allocation profiling disabled" do before do settings.profiling.allocation_enabled = false