Skip to content

Commit 15f6fc6

Browse files
authored
Add new mem:check task to run Valgrind in CI (#26)
1 parent dd47651 commit 15f6fc6

File tree

6 files changed

+105
-2
lines changed

6 files changed

+105
-2
lines changed

.github/workflows/memcheck.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
name: Memcheck
3+
4+
on:
5+
workflow_dispatch:
6+
inputs:
7+
ruby-version:
8+
description: 'Ruby version to memcheck'
9+
required: true
10+
default: '3.1'
11+
type: choice
12+
options:
13+
- 'head'
14+
- '3.1'
15+
- '3.0'
16+
- '2.7'
17+
push:
18+
19+
jobs:
20+
memcheck:
21+
name: Memcheck
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@v3
25+
26+
- uses: oxidize-rb/actions/setup-ruby-and-rust@main
27+
with:
28+
ruby-version: ${{ inputs.ruby-version || '3.1' }}
29+
bundler-cache: true
30+
cargo-cache: true
31+
cache-version: v1
32+
33+
- name: Install deps
34+
run: |
35+
bundle config unset deployment
36+
bundle add ruby_memcheck & # avoid usage in Gemfile bc it pulls in nokogiri
37+
sudo apt install -y valgrind &
38+
wait
39+
bundle config set deployment true
40+
41+
- name: Run "mem:check" task
42+
env:
43+
RSPEC_FORMATTER: "progress"
44+
RSPEC_FAILURE_EXIT_CODE: "0"
45+
run: |
46+
if ! bundle exec rake mem:check; then
47+
echo "::error::Valgrind memory check failed, for more info please see ./suppressions/readme.md"
48+
exit 1
49+
fi

.rspec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
--format documentation
21
--color
32
--require spec_helper

rakelib/mem.rake

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,23 @@ namespace :mem do
5757
end
5858
end
5959
end
60+
61+
if RbConfig::CONFIG["host_os"] == "linux"
62+
begin
63+
require "ruby_memcheck"
64+
require "ruby_memcheck/rspec/rake_task"
65+
66+
RubyMemcheck.config(binary_name: "ext")
67+
68+
RubyMemcheck::RSpec::RakeTask.new(check: :compile)
69+
rescue LoadError
70+
task :check do
71+
abort 'Please add `gem "ruby_memcheck"` to your Gemfile to use the "mem:check" task'
72+
end
73+
end
74+
else
75+
task :check do
76+
abort 'The "mem:check" task is only available on Linux'
77+
end
78+
end
6079
end

spec/spec_helper.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ def compile(wat)
2424

2525
config.include_context("default lets")
2626

27+
# So memcheck steps can still pass if RSpec fails
28+
config.failure_exit_code = ENV.fetch("RSPEC_FAILURE_EXIT_CODE", 1).to_i
29+
config.default_formatter = ENV.fetch("RSPEC_FORMATTER", "doc")
30+
2731
# Enable flags like --only-failures and --next-failure
28-
config.example_status_persistence_file_path = ".rspec_status"
32+
config.example_status_persistence_file_path = ".rspec_status" unless ENV["CI"]
2933

3034
# Disable RSpec exposing methods globally on `Module` and `main`
3135
config.disable_monkey_patching!
@@ -43,3 +47,5 @@ def compile(wat)
4347
end
4448
end
4549
end
50+
51+
at_exit { GC.start(full_mark: true) }

suppressions/readme.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Suppressions
2+
3+
This folder includes Valgrind suppressions used by the
4+
[`ruby_memcheck`][ruby_memcheck] gem. If you the `memcheck` CI job fails, you
5+
may need to add a suppression to `ruby-3.1.supp` to fix it.
6+
7+
[ruby_memcheck]: https://github.com/Shopify/ruby_memcheck

suppressions/ruby-3.1.supp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
Rust probes for statx(buf)
3+
Memcheck:Param
4+
statx(buf)
5+
...
6+
fun:*try_statx*
7+
...
8+
}
9+
{
10+
Rust probes for statx(file_name)
11+
Memcheck:Param
12+
statx(file_name)
13+
...
14+
fun:*try_statx*
15+
...
16+
}
17+
{
18+
Valgrind is detecting a "Invalid read of size 8" during this process, not sure why
19+
Memcheck:Addr8
20+
fun:each_location.constprop.1
21+
fun:gc_mark_children
22+
...
23+
}

0 commit comments

Comments
 (0)