Skip to content

[PROF-15076] Fix GC profiling being disabled on Ruby 3.2.10/3.2.11#5894

Merged
ivoanjo merged 12 commits into
masterfrom
ivoanjo/prof-15076-gc-profiling-disabled-ruby-3.2.11
Jun 16, 2026
Merged

[PROF-15076] Fix GC profiling being disabled on Ruby 3.2.10/3.2.11#5894
ivoanjo merged 12 commits into
masterfrom
ivoanjo/prof-15076-gc-profiling-disabled-ruby-3.2.11

Conversation

@ivoanjo

@ivoanjo ivoanjo commented Jun 12, 2026

Copy link
Copy Markdown
Member

What does this PR do?

This PR introduces a new RubyVersion helper and moves profiling code to use it.

This fixes a bug with our GC profiling logic testing using strings directly, and 3.2.10/3.2.11 are unfortunately < "3.2.3", e.g.:

if ...
    (RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3")
  logger.warn(
    "Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling GC profiling would cause " \
    "crashes (https://bugs.ruby-lang.org/issues/18464). GC profiling has been disabled."
  )

Motivation:

Fix feature being mistakenly broken on latest Ruby patch versions.

Change log entry

Yes. Fix GC profiling being disabled on Ruby 3.2.10/3.2.11

Additional Notes:

I admit I knew about this footgun, but there hadn't been .10 and above releases in a while and I kinda disliked the verboseness of doing the check using Gem::Version or the like.

With the addition of the helper, we can do it correctly and cleanly.

I've also changed every other use in profiling of RUBY_VERSION.

I'm preparing a follow-up PR to change this in more places in dd-trace-rb, but wanted to get this out as a smaller fix first.

Finally, I've split the change into step-by-step commits, and I recommend reviewing commit-by-commit.

How to test the change?

This change has test coverage.

ivoanjo added 4 commits June 12, 2026 11:28
**What does this PR do?**

This PR introduces a new `RubyVersion` helper and moves profiling code
to use it.

This fixes a bug with our GC profiling logic testing using
strings directly, and `3.2.10`/`3.2.11` are unfortunately `< "3.2.3"`,
e.g.:

```ruby
if ...
    (RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3")
  logger.warn(
    "Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling GC profiling would cause " \
    "crashes (https://bugs.ruby-lang.org/issues/18464). GC profiling has been disabled."
  )
```

**Motivation:**

Fix feature being mistakenly broken on latest Ruby patch versions.

**Additional Notes:**

I admit I knew about this footgun, but there hadn't been .10 and above
releases in a while and I kinda disliked the verboseness of doing the
check using `Gem::Version` or the like.

With the addition of the helper, we can do it correctly and cleanly.

I've also changed every other use in profiling of `RUBY_VERSION`.

**How to test the change?**

This change has test coverage.
@ivoanjo
ivoanjo requested review from a team as code owners June 12, 2026 16:35
@ivoanjo
ivoanjo requested a review from eregon June 12, 2026 16:35
@dd-octo-sts dd-octo-sts Bot added core Involves Datadog core libraries profiling Involves Datadog profiling labels Jun 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 632246f1cc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread lib/datadog/profiling/ext/dir_monkey_patches.rb Outdated
@datadog-datadog-prod-us1

datadog-datadog-prod-us1 Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 36.84%
Overall Coverage: 89.87% (-0.01%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 8f3d166 | Docs | Datadog PR Page | Give us feedback!

@eregon eregon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good cleanup but I'm not very fond of ~> it's quite verbose (needs an extra digit when most cases want to check e.g. >= A.B) and error-prone (e.g. when forgetting to add the extra digit) and probably quite slow.
I'd prefer something like if RubyVersion >= 3.4/if RubyVersion >= [3, 4]/if RubyVersion >= "3.4"

Comment thread lib/datadog/ruby_version.rb Outdated
Comment thread lib/datadog/ruby_version.rb Outdated
Comment thread lib/datadog/profiling/ext/dir_monkey_patches.rb Outdated
Comment thread lib/datadog/profiling/ext/dir_monkey_patches.rb Outdated
Comment thread spec/datadog/profiling/native_extension_spec.rb Outdated
Comment thread spec/datadog/profiling/spec_helper.rb
@eregon

eregon commented Jun 15, 2026

Copy link
Copy Markdown
Member

Thinking out loud, for cases like 3.1.0 - 3.1.2 we could have:

if RubyVersion.between?("3.1.0", "3.1.2") # There is Comparable#between? which we might be able to reuse
if RubyVersion.in?("3.1.0".."3.1.2")

Though just this is fine too:

if RubyVersion >= "3.1.0" && RubyVersion <= "3.1.2"

((or (ab)use the fact such checks are typically single-digits and ("3.1.0".."3.1.2").include?(RUBY_VERSION)))

@ivoanjo

ivoanjo commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

Thinking out loud, for cases like 3.1.0 - 3.1.2 we could have

I agree; yet, when I looked at it, I think we have less than 5? 10? of those, so having the extra helper didn't seem worth the extra code.

Comment thread lib/datadog/ruby_version.rb Outdated
@pr-commenter

pr-commenter Bot commented Jun 15, 2026

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2026-06-15 16:42:52

Comparing candidate commit b7af24e in PR branch ivoanjo/prof-15076-gc-profiling-disabled-ruby-3.2.11 with baseline commit 202d652 in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 48 metrics, 1 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

@ivoanjo
ivoanjo merged commit 9f17636 into master Jun 16, 2026
589 checks passed
@ivoanjo
ivoanjo deleted the ivoanjo/prof-15076-gc-profiling-disabled-ruby-3.2.11 branch June 16, 2026 08:12
@dd-octo-sts dd-octo-sts Bot added this to the 2.36.0 milestone Jun 16, 2026
ivoanjo added a commit that referenced this pull request Jun 16, 2026
**What does this PR do?**

In #5894 we added a new
`RubyVersion` helper to have a short and always-correct way of guarding
code that needs to behave differently across Ruby versions.

In that PR I deliberately did not touch code outside of profiling, and
this is the follow-up that adds the helper to the rest of dd-trace-rb.

**Motivation:**

Standardize on `RubyVersion` as the common way of testing
`RUBY_VERSION`.

**Additional Notes:**

N/A

**How to test the change?**

This change is covered by the existing tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Involves Datadog core libraries profiling Involves Datadog profiling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants