Skip to content

Add Valgrind memcheck (ruby_memcheck) for the C extension - #147

Open
Watson1978 wants to merge 1 commit into
SpringMT:mainfrom
Watson1978:feature/valgrind-memcheck
Open

Add Valgrind memcheck (ruby_memcheck) for the C extension#147
Watson1978 wants to merge 1 commit into
SpringMT:mainfrom
Watson1978:feature/valgrind-memcheck

Conversation

@Watson1978

Copy link
Copy Markdown
Contributor

Summary

This adds Shopify's ruby_memcheck so the spec suite can be run under Valgrind's memcheck:

rake spec:valgrind

Running Valgrind against a Ruby C extension is normally impractical, because the interpreter itself produces a large volume of reports that have nothing to do with the extension. ruby_memcheck wraps Valgrind and applies a heuristic that only surfaces errors whose stack trace passes through the extension's .so, which makes the output usable. It is the same tool Shopify runs on nokogiri and liquid-c.

The task layout follows rmagick/rmagick#1716 — Linux-only guard, valgrind: :compile prerequisite, dependency added with a platform guard.

What is in this PR

  • ruby_memcheck as a Linux-only development dependency in the Gemfile. Valgrind is not usable in practice on macOS or Windows, and the RUBY_PLATFORM.include?('linux') guard keeps bundle install working there. It goes in the Gemfile rather than the gemspec so the packaged gem stays platform-agnostic.
  • A rake spec:valgrind task in the Rakefile. It disables YJIT under Valgrind (they interfere, adding noise and slowdown) and fails early with a clear message when Valgrind is not installed. If ruby_memcheck itself is missing, the task is simply not defined rather than breaking the Rakefile.

No suppression file is included: on the current tree the suite reports nothing that needs silencing.

Current result

Clean. rake spec:valgrind exits 0 with zero reports attributed to the extension — no invalid accesses, no leaks — in about 75 seconds for the 67 examples.

🤖 Generated with Claude Code

Running the suite under Valgrind on a Ruby C extension is normally impractical:
the interpreter itself produces a large volume of reports that have nothing to
do with the extension. ruby_memcheck wraps Valgrind and only surfaces errors
whose stack trace passes through the extension's .so, which makes the output
usable. It is the same tool Shopify runs on nokogiri and liquid-c.

    rake spec:valgrind

The task is Linux-only, since Valgrind is not usable in practice on macOS or
Windows, and the dependency carries the same guard so bundle install keeps
working there. If ruby_memcheck is not installed the task is simply not
defined, rather than breaking the Rakefile. YJIT is disabled under Valgrind
because the two interfere, adding noise and slowdown.

The suite reports nothing on the current tree, so no suppression file is
needed. Verified that the task has teeth by running it against the
use-after-free of a stream's borrowed CDict/DDict: it reports 113 Invalid read
records, correctly attributed through ZSTD_CCtx_init_compressStream2 and
ZSTD_decompressBegin_usingDDict inside zstdruby.so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant