Skip to content

Commit b7b99b2

Browse files
authored
Merge pull request #3848 from DataDog/ivoanjo/prof-10128-workaround-flaky-spec
[PROF-10128] Workaround heap profiling flaky spec on Ruby 3.3+
2 parents a534220 + 246d8cd commit b7b99b2

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

spec/datadog/profiling/stack_recorder_spec.rb

+15-16
Original file line numberDiff line numberDiff line change
@@ -1011,31 +1011,30 @@ def sample_allocation(obj)
10111011

10121012
it "includes heap recorder snapshot" do
10131013
live_objects = []
1014+
1015+
# NOTE: We've seen some flakiness in this spec on Ruby 3.3 when the `dead_heap_samples` were allocated after
1016+
# the `live_heap_samples`. Our working theory is that this is something like
1017+
# https://bugs.ruby-lang.org/issues/19460 biting us again (e.g. search for this URL on this file and you'll see
1018+
# a similar comment). Specifically, it looks like in some situations Ruby still keeps a reference to the last
1019+
# allocated object _somewhere_, which makes the GC not collect that object, even though there are no actual
1020+
# references to it. Because the GC doesn't clean the object, the heap recorder still keeps its record alive,
1021+
# and so the test causes flakiness.
1022+
# See also the discussion on commit 2fc03d5ae5860d4e9a75ce3825fba95ed288a1 for an earlier attempt at fixing this.
1023+
dead_heap_samples = 10
1024+
dead_heap_samples.times do |_i|
1025+
obj = {}
1026+
sample_allocation(obj)
1027+
end
1028+
10141029
live_heap_samples = 6
10151030
live_heap_samples.times do |i|
10161031
obj = Object.new
10171032
obj.freeze if i.odd? # Freeze every other object
10181033
sample_allocation(obj)
10191034
live_objects << obj
10201035
end
1021-
dead_heap_samples = 10
1022-
dead_heap_samples.times do |_i|
1023-
obj = Object.new
1024-
sample_allocation(obj)
1025-
end
10261036
GC.start # All dead objects above will be GCed, all living strings will have age = 0
10271037

1028-
# @ivoanjo: For some weird reason, the last object sampled in the "dead_heap_samples" does not always
1029-
# get collected the first time, leading to a flaky spec.
1030-
# I was able to reproduce it with `rspec spec/datadog/profiling --seed 48141 --fail-fast` and it's
1031-
# kinda bizarre since e.g. if you add one more `Object.new` it also stops flaking, so is it perhaps
1032-
# related to Ruby's conservative GC?
1033-
# I've bisected this and undoing 3d4b7fcf30b529b191ca737ae13629eb27b8ab63 also makes the flakiness
1034-
# go away, but again, that change doesn't seem to have anything to do with GC.
1035-
# As the weird behavior is transitory, e.g. it provably goes away on the next GC, I'll go with this
1036-
# workaround for now.
1037-
GC.start
1038-
10391038
begin
10401039
# Allocate some extra objects in a block with GC disabled and ask for a serialization
10411040
# to ensure these strings have age=0 by the time we try to serialize the profile

0 commit comments

Comments
 (0)