Skip to content

Commit

Permalink
Merge pull request #246 from DataDog/anmarchenko/memcheck_tests
Browse files Browse the repository at this point in the history
[SDTEST-744] add memory leaks tests with ruby_memcheck
  • Loading branch information
anmarchenko authored Oct 8, 2024
2 parents c12ad86 + 157b0d8 commit bbc6b66
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 1 deletion.
15 changes: 15 additions & 0 deletions .github/workflows/test-memory-leaks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Test for memory leaks
on: [push]
jobs:
test-memcheck:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.4.0-preview1 # TODO: Use stable version once 3.4 is out
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
bundler: latest
cache-version: v1 # bump this to invalidate cache
- run: sudo apt-get update && (sudo apt-get install -y valgrind || sleep 5 && sudo apt-get install -y valgrind) && valgrind --version
- run: bundle exec rake compile spec:ddcov_memcheck
4 changes: 3 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ gem "pimpmychangelog", ">= 0.1.2"
gem "simplecov"
gem "simplecov-cobertura", "~> 2.1.0"

# type checking
# type checks, memory checks, etc.
group :check do
if RUBY_VERSION >= "3.0.0" && RUBY_PLATFORM != "java"
gem "rbs", "~> 3.5.0", require: false
gem "steep", "~> 1.7.0", require: false
end

gem "ruby_memcheck", ">= 3" if RUBY_VERSION >= "3.4.0" && RUBY_PLATFORM != "java"
end

# development dependencies for vscode integration and debugging
Expand Down
26 changes: 26 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ require "rspec/core/rake_task"
require "yard"
require "rake/extensiontask"

if Gem.loaded_specs.key? "ruby_memcheck"
require "ruby_memcheck"
require "ruby_memcheck/rspec/rake_task"

RubyMemcheck.config(
# If there's an error, print the suppression for that error, to allow us to easily skip such an error if it's
# a false-positive / something in the VM we can't fix.
valgrind_generate_suppressions: true,
# This feature provides better quality data -- I couldn't get good output out of ruby_memcheck without it.
use_only_ruby_free_at_exit: true
)
end

RSpec::Core::RakeTask.new(:spec)

Dir.glob("tasks/*.rake").each { |r| import r }
Expand Down Expand Up @@ -159,6 +172,19 @@ namespace :spec do
t.pattern = "spec/datadog/ci/git/**/*_spec.rb"
t.rspec_opts = args.to_a.join(" ")
end

# ddcov test impact analysis tool with memcheck
desc ""
if Gem.loaded_specs.key?("ruby_memcheck")
RubyMemcheck::RSpec::RakeTask.new(:ddcov_memcheck) do |t, args|
t.pattern = "spec/ddcov/**/*_spec.rb"
t.rspec_opts = args.to_a.join(" ")
end
else
task :ddcov_memcheck do
raise "Memcheck requires the ruby_memcheck gem to be installed"
end
end
end

desc "CI task; it runs all tests for current version of Ruby"
Expand Down
1 change: 1 addition & 0 deletions spec/datadog/ci/release_gem_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
|tasks
|yard
|vendor/rbs
|suppressions
)/
}x

Expand Down
53 changes: 53 additions & 0 deletions suppressions/ruby-3.4.supp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# This is a valgrind suppression configuration file.
#
# We use it together with the ruby_memcheck gem to find issues in the datadog-ci-rb native extensions; in some cases
# we need to ignore potential issues as they're not something we can fix (e.g. outside our code.)
#
# See https://valgrind.org/docs/manual/manual-core.html#manual-core.suppress for details.

# When a Ruby process forks, it looks like Ruby doesn't clean up the memory of old threads?
{
ruby-native-thread-memory
Memcheck:Leak
fun:calloc
fun:calloc1
fun:rb_gc_impl_calloc
fun:native_thread_alloc
fun:native_thread_create_dedicated
fun:native_thread_create
fun:thread_create_core
...
}

# When a Ruby process forks, it looks like Ruby doesn't clean up the memory of old threads?
{
ruby-native-thread-memory-2
Memcheck:Leak
fun:calloc
fun:calloc1
fun:objspace_xcalloc
fun:ruby_xcalloc_body
fun:native_thread_alloc
fun:native_thread_create_dedicated
fun:native_thread_create
fun:thread_create_core
...
}

# We don't care about the pkg-config external tool
{
pkg-config-memory
Memcheck:Leak
...
obj:/usr/bin/pkg-config
...
}

# We don't care about the tr external tool
{
pkg-config-memory
Memcheck:Leak
...
obj:/usr/bin/tr
...
}

0 comments on commit bbc6b66

Please sign in to comment.