Skip to content

Add new mem:check task to run Valgrind in CI #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/memcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
name: Memcheck

on:
workflow_dispatch:
inputs:
ruby-version:
description: 'Ruby version to memcheck'
required: true
default: '3.1'
type: choice
options:
- 'head'
- '3.1'
- '3.0'
- '2.7'
push:

jobs:
memcheck:
name: Memcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- uses: oxidize-rb/actions/setup-ruby-and-rust@main
with:
ruby-version: ${{ inputs.ruby-version || '3.1' }}
bundler-cache: true
cargo-cache: true
cache-version: v1

- name: Install deps
run: |
bundle config unset deployment
bundle add ruby_memcheck & # avoid usage in Gemfile bc it pulls in nokogiri
sudo apt install -y valgrind &
wait
bundle config set deployment true

- name: Run "mem:check" task
env:
RSPEC_FORMATTER: "progress"
RSPEC_FAILURE_EXIT_CODE: "0"
run: |
if ! bundle exec rake mem:check; then
echo "::error::Valgrind memory check failed, for more info please see ./suppressions/readme.md"
exit 1
fi
1 change: 0 additions & 1 deletion .rspec
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
--format documentation
--color
--require spec_helper
19 changes: 19 additions & 0 deletions rakelib/mem.rake
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,23 @@ namespace :mem do
end
end
end

if RbConfig::CONFIG["host_os"] == "linux"
begin
require "ruby_memcheck"
require "ruby_memcheck/rspec/rake_task"

RubyMemcheck.config(binary_name: "ext")

RubyMemcheck::RSpec::RakeTask.new(check: :compile)
rescue LoadError
task :check do
abort 'Please add `gem "ruby_memcheck"` to your Gemfile to use the "mem:check" task'
end
end
else
task :check do
abort 'The "mem:check" task is only available on Linux'
end
end
end
8 changes: 7 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ def compile(wat)

config.include_context("default lets")

# So memcheck steps can still pass if RSpec fails
config.failure_exit_code = ENV.fetch("RSPEC_FAILURE_EXIT_CODE", 1).to_i
config.default_formatter = ENV.fetch("RSPEC_FORMATTER", "doc")

# Enable flags like --only-failures and --next-failure
config.example_status_persistence_file_path = ".rspec_status"
config.example_status_persistence_file_path = ".rspec_status" unless ENV["CI"]

# Disable RSpec exposing methods globally on `Module` and `main`
config.disable_monkey_patching!
Expand All @@ -43,3 +47,5 @@ def compile(wat)
end
end
end

at_exit { GC.start(full_mark: true) }
7 changes: 7 additions & 0 deletions suppressions/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Suppressions

This folder includes Valgrind suppressions used by the
[`ruby_memcheck`][ruby_memcheck] gem. If you the `memcheck` CI job fails, you
may need to add a suppression to `ruby-3.1.supp` to fix it.

[ruby_memcheck]: https://github.com/Shopify/ruby_memcheck
23 changes: 23 additions & 0 deletions suppressions/ruby-3.1.supp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
Rust probes for statx(buf)
Memcheck:Param
statx(buf)
...
fun:*try_statx*
...
}
{
Rust probes for statx(file_name)
Memcheck:Param
statx(file_name)
...
fun:*try_statx*
...
}
{
Valgrind is detecting a "Invalid read of size 8" during this process, not sure why
Memcheck:Addr8
fun:each_location.constprop.1
fun:gc_mark_children
...
}