Skip to content

[NO-TICKET] Profiling: Add integration test with GC.stress - #6302

Merged
ivoanjo merged 6 commits into
masterfrom
ivoanjo/gc-stress-testcase
Sep 23, 2026
Merged

ivoanjo merged 6 commits into
masterfrom
ivoanjo/gc-stress-testcase

Conversation

@ivoanjo

@ivoanjo ivoanjo commented Sep 11, 2026

Copy link
Copy Markdown
Member

What does this PR do?

This PR adds a new "integration" test to the
cpu_and_wall_time_worker_spec.rb where we run the profiler for a brief period with all features enabled under Ruby's GC.stress setting.

Motivation:

In #6242 and #6245 we were able to reproduce those bugs using GC.stress.

To try to catch possible similar issues in the future, it seemed useful to have an integration test where we ran the profiler with GC.stress.

Change log entry

None.

Additional Notes:

The big downside of GC.stress is how slow it makes the test suite. On my workspace, it takes around 20-30s to run just this one new testcase, which is why I've made it only run in CI as I really value quick iteration on our testsuite and having mega-slow tests breaks that.

I also evaluated how feasible it would be to run the entire cpu_and_wall_time_worker_spec.rb with GC.stress and unfortunately the answer isn't great -- it would take hours AND in particular it would need modifications since we have a bunch of timeouts for cross-thread stuff that would need heavy tweaking.

Ideas on how we could get more coverage without a lot of work are welcome ;)

How to test the change?

Validate CI is green and this test passes!

@ivoanjo
ivoanjo requested a review from a team as a code owner September 11, 2026 08:28
@ivoanjo
ivoanjo requested a review from eregon September 11, 2026 08:28
@dd-octo-sts dd-octo-sts Bot added the dev/testing Involves testing processes (e.g. RSpec) label Sep 11, 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: 0aca274441

ℹ️ 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 spec/datadog/profiling/collectors/cpu_and_wall_time_worker_spec.rb
Comment thread spec/datadog/profiling/collectors/cpu_and_wall_time_worker_spec.rb
@datadog-official

datadog-official Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Tests

✅ All CI checks and tests passed.

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
• Patch Coverage: 100.00%
• Overall Coverage: 90.36% (-0.01%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 8631f6a | Docs | View more details | Give us feedback!

Comment thread spec/datadog/profiling/collectors/cpu_and_wall_time_worker_spec.rb Outdated
Comment thread spec/datadog/profiling/collectors/cpu_and_wall_time_worker_spec.rb Outdated
Comment thread spec/datadog/profiling/collectors/cpu_and_wall_time_worker_spec.rb Outdated
@ivoanjo

ivoanjo commented Sep 11, 2026

Copy link
Copy Markdown
Member Author

I saw this fail in CI with

2026-09-11T08:41:19.9887683Z W, [2026-09-11T08:41:17.376742 #14404] WARN -- datadog: [datadog] CpuAndWallTimeWorker thread error. Operation: "rescued_sample_from_postponed_job" Cause: RuntimeError: BUG: Unexpected CPU time going backwards between samples Location: /usr/local/lib/ruby/3.3.0/timeout.rb:110:in `sleep'

I actually had an older WIP fix for that in #6021 which I haven't yet finished, so I'll hold on merging this one a few days until I can fix that one.

@ivoanjo

ivoanjo commented Sep 23, 2026

Copy link
Copy Markdown
Member Author

Update: Flaky issue I mentioned above will be fixed by #6364 .

I'll rebase this PR and stack it on top of that one, to avoid landing a new test that triggers flaky behavior before the PR that fixes the flaky behavior ;)

ivoanjo and others added 3 commits September 23, 2026 10:50
**What does this PR do?**

This PR adds a new "integration" test to the
`cpu_and_wall_time_worker_spec.rb` where we run the profiler for a brief
period with all features enabled under Ruby's `GC.stress` setting.

**Motivation:**

In #6242 and
#6245 we were able to
reproduce those bugs using `GC.stress`.

To try to catch possible similar issues in the future, it seemed
useful to have an integration test where we ran the profiler with
`GC.stress`.

**Additional Notes:**

The big downside of `GC.stress` is how slow it makes the test suite.
On my workspace, it takes around 20-30s to run just this one new
testcase, which is why I've made it only run in CI as I really value
quick iteration on our testsuite and having mega-slow tests breaks that.

I also evaluated how feasible it would be to run the entire
`cpu_and_wall_time_worker_spec.rb` with `GC.stress` and unfortunately
the answer isn't great -- it would take hours AND in particular it would
need modifications since we have a bunch of timeouts for cross-thread
stuff that would need heavy tweaking.

Ideas on how we could get more coverage without a lot of work are
welcome ;)

**How to test the change?**

Validate CI is green and this test passes!
Co-authored-by: Benoit Daloze <eregontp@gmail.com>
@ivoanjo
ivoanjo force-pushed the ivoanjo/gc-stress-testcase branch from 0b77e23 to 0857e9c Compare September 23, 2026 10:51
@ivoanjo
ivoanjo requested a review from a team as a code owner September 23, 2026 10:51
@ivoanjo
ivoanjo requested review from vpellan and removed request for a team September 23, 2026 10:51
@dd-octo-sts dd-octo-sts Bot added the profiling Involves Datadog profiling label Sep 23, 2026
@ivoanjo
ivoanjo changed the base branch from master to ivoanjo/fix-cpu-time-going-backwards September 23, 2026 10:51
@eregon

eregon commented Sep 23, 2026

Copy link
Copy Markdown
Member

Regarding this spec being slow, maybe we should look at the serialized profile to find out which lines take longest?
It might be less important to have some of them inside the GC.stress region.

@ivoanjo

ivoanjo commented Sep 23, 2026

Copy link
Copy Markdown
Member Author

Regarding this spec being slow, maybe we should look at the serialized profile to find out which lines take longest?
It might be less important to have some of them inside the GC.stress region.

Yeap, I didn't mention it, the PR already incorporates some of that -- I added the pre-create instances thing for instance.

A very big one is https://github.com/DataDog/dd-trace-rb/blob/master/spec/spec_helper.rb#L330 (since we start a new thread) but there's also a few others so I hesitated in trying too hard in that direction.

Base automatically changed from ivoanjo/fix-cpu-time-going-backwards to master September 23, 2026 14:30
@ivoanjo
ivoanjo enabled auto-merge September 23, 2026 14:37
...otherwise we might (as just happened in CI) end up in a situation
where e.g. no allocation samples are taken.
@ivoanjo
ivoanjo merged commit c47e5e8 into master Sep 23, 2026
332 checks passed
@ivoanjo
ivoanjo deleted the ivoanjo/gc-stress-testcase branch September 23, 2026 16:19
@dd-octo-sts dd-octo-sts Bot added this to the 2.44.0 milestone Sep 23, 2026
hayat01sh1da pushed a commit to hayat01sh1da/dd-trace-rb that referenced this pull request Sep 24, 2026
… due to GC

**What does this PR do?**

This PR fixes the profiler stopping with
"BUG: Unexpected CPU time going backwards between samples" if we get
very unlucky and a GC gets triggered by our `thread_list()` call.

The issue happened because of:
1. We recorded the current thread's CPU-time
2. `thread_list()` triggered GC
3. GC profiling hook advances the current thread's CPU-time
4. After `thread_list()` returned, we tried to
   `update_cpu_time_since_previous_sample` using old timestamp
   from step 1, resulting in a negative delta, triggering the assert

**Motivation:**

Fix bug that leads to profiler stopping.

**Additional Notes:**

This has flown under the radar for a long time because it's quite
rare that `thread_list()` actually triggers GC.

It did show up as a flaky issue in
DataDog#6302 because that PR
adds a test that uses `GC.stress` to trigger GC more often.

**How to test the change?**

I've chosen not to add more coverage as the one that DataDog#6302 will add
has already proven to trigger the issue.

(I still decided to keep this as a separate, small PR since in
the issue already existed independent of that PR)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dev/testing Involves testing processes (e.g. RSpec) profiling Involves Datadog profiling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants