ruby_memcheck 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/README.md +4 -3
- data/lib/ruby_memcheck/configuration.rb +19 -1
- data/lib/ruby_memcheck/suppression.rb +25 -0
- data/lib/ruby_memcheck/test_task.rb +6 -3
- data/lib/ruby_memcheck/valgrind_error.rb +3 -1
- data/lib/ruby_memcheck/version.rb +1 -1
- data/lib/ruby_memcheck.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d7e2556e802cceebbd1607895ed319b54037e2a945586f8fe65e9f6bda0928c
|
4
|
+
data.tar.gz: 3cba76f62de7ad396458d651a272d660456e362a85c1c6a67ac6ae688b3e4c30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e849c1bcfc9947293939452298c344acd71136dd7b617bb3edfc07c7b8122a9bc366e1e57a83d86293ed284569121185d465fd9e47959a9e9e0b6579b212022
|
7
|
+
data.tar.gz: 3131ae9a995bcd2e9f9fcab7f7bfb8b99c3449eadb12d9bfad0366681971d3c3fa7234e194fbf7e5c9a41583d18814cc59aad7802836ba1d075e0d6893be0e1d
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -83,14 +83,15 @@ The easiest way to use this gem is to use it on your test suite using rake.
|
|
83
83
|
RubyMemcheck::TestTask.new(valgrind: :compile, &test_config)
|
84
84
|
end
|
85
85
|
```
|
86
|
-
1.
|
86
|
+
1. At the top of your `test_helper.rb`/`spec_helper.rb` (or whatever file sets up your test suite), add this line:
|
87
87
|
|
88
88
|
```ruby
|
89
|
-
|
89
|
+
at_exit { GC.start }
|
90
90
|
```
|
91
91
|
|
92
|
-
This will ensure that the Garbage Collector is ran before Ruby shuts down. This will reduce the number of false-positives.
|
92
|
+
Place this line as close to the top of the file as possible, before any requires in the file (especially before the call to `require "minitest/autorun"`). This will ensure that the Garbage Collector is ran before Ruby shuts down. This will reduce the number of false-positives.
|
93
93
|
1. You're ready to run your test suite with Valgrind using `rake test:valgrind`! Note that this will take a while to run because Valgrind will make Ruby significantly slower.
|
94
|
+
1. (Optional) If you find false-positives in the output, you can create suppression files in a `suppressions` directory in the root directory of your gem. In this directory, you can create [Valgrind suppression files](https://wiki.wxwidgets.org/Valgrind_Suppression_File_Howto). The most basic suppression file is `your_binary_name_ruby.supp`. If you want some suppressions for only specific versions of Ruby, you can add the Ruby version to the filename. For example, `your_binary_name_ruby-3.supp` will suppress for any Rubies with a major version of 3 (e.g. 3.0.0, 3.1.1, etc.), while suppression file `your_binary_name_ruby-3.1.supp` will only be used for Ruby with a major and minor version of 3.1 (e.g. 3.1.0, 3.1.1, etc.).
|
94
95
|
|
95
96
|
## License
|
96
97
|
|
@@ -10,11 +10,13 @@ module RubyMemcheck
|
|
10
10
|
"--leak-check=full",
|
11
11
|
"--show-leak-kinds=definite",
|
12
12
|
].freeze
|
13
|
+
DEFAULT_VALGRIND_SUPPRESSIONS_DIR = "suppressions"
|
13
14
|
DEFAULT_SKIPPED_RUBY_FUNCTIONS = [
|
14
15
|
/\Arb_check_funcall/,
|
15
16
|
/\Arb_enc_raise\z/,
|
16
17
|
/\Arb_exc_raise\z/,
|
17
18
|
/\Arb_funcall/,
|
19
|
+
/\Arb_intern/,
|
18
20
|
/\Arb_ivar_set\z/,
|
19
21
|
/\Arb_raise\z/,
|
20
22
|
/\Arb_rescue/,
|
@@ -30,6 +32,7 @@ module RubyMemcheck
|
|
30
32
|
ruby: FileUtils::RUBY,
|
31
33
|
valgrind: DEFAULT_VALGRIND,
|
32
34
|
valgrind_options: DEFAULT_VALGRIND_OPTIONS,
|
35
|
+
valgrind_suppressions_dir: DEFAULT_VALGRIND_SUPPRESSIONS_DIR,
|
33
36
|
skipped_ruby_functions: DEFAULT_SKIPPED_RUBY_FUNCTIONS,
|
34
37
|
valgrind_xml_file: Tempfile.new,
|
35
38
|
output_io: $stderr
|
@@ -37,7 +40,9 @@ module RubyMemcheck
|
|
37
40
|
@binary_name = binary_name
|
38
41
|
@ruby = ruby
|
39
42
|
@valgrind = valgrind
|
40
|
-
@valgrind_options =
|
43
|
+
@valgrind_options =
|
44
|
+
valgrind_options +
|
45
|
+
get_valgrind_suppression_files(valgrind_suppressions_dir).map { |f| "--suppressions=#{f}" }
|
41
46
|
@skipped_ruby_functions = skipped_ruby_functions
|
42
47
|
@output_io = output_io
|
43
48
|
|
@@ -89,5 +94,18 @@ module RubyMemcheck
|
|
89
94
|
false
|
90
95
|
end
|
91
96
|
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def get_valgrind_suppression_files(dir)
|
101
|
+
full_ruby_version = "#{RUBY_ENGINE}-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
|
102
|
+
versions = [full_ruby_version]
|
103
|
+
(0..3).reverse_each { |i| versions << full_ruby_version.split(".")[0, i].join(".") }
|
104
|
+
versions << RUBY_ENGINE
|
105
|
+
|
106
|
+
versions.map do |version|
|
107
|
+
Dir[File.join(dir, "#{binary_name}_#{version}.supp")]
|
108
|
+
end.flatten
|
109
|
+
end
|
92
110
|
end
|
93
111
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyMemcheck
|
4
|
+
class Suppression
|
5
|
+
attr_reader :root
|
6
|
+
|
7
|
+
def initialize(configuration, suppression_node)
|
8
|
+
@root = suppression_node
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
return "" if root.nil?
|
13
|
+
|
14
|
+
str = StringIO.new
|
15
|
+
str << "{\n"
|
16
|
+
str << " #{root.at_xpath("sname").content}\n"
|
17
|
+
str << " #{root.at_xpath("skind").content}\n"
|
18
|
+
root.xpath("./sframe/fun | ./sframe/obj").each do |frame|
|
19
|
+
str << " #{frame.name}:#{frame.content}\n"
|
20
|
+
end
|
21
|
+
str << "}\n"
|
22
|
+
str.string
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -20,7 +20,7 @@ module RubyMemcheck
|
|
20
20
|
def ruby(*args, **options, &block)
|
21
21
|
command = configuration.command(args)
|
22
22
|
sh(command, **options) do |ok, res|
|
23
|
-
if
|
23
|
+
if configuration.valgrind_xml_file
|
24
24
|
parse_valgrind_output
|
25
25
|
unless errors.empty?
|
26
26
|
output_valgrind_errors
|
@@ -35,10 +35,13 @@ module RubyMemcheck
|
|
35
35
|
private
|
36
36
|
|
37
37
|
def parse_valgrind_output
|
38
|
+
require "nokogiri"
|
39
|
+
|
38
40
|
@errors = []
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
+
Nokogiri::XML::Reader(File.open(configuration.valgrind_xml_file.to_path)).each do |node|
|
43
|
+
next unless node.name == "error" && node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
|
44
|
+
error_xml = Nokogiri::XML::Document.parse(node.outer_xml).root
|
42
45
|
error = ValgrindError.new(configuration, error_xml)
|
43
46
|
next if error.skip?
|
44
47
|
@errors << error
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module RubyMemcheck
|
4
4
|
class ValgrindError
|
5
|
-
attr_reader :kind, :msg, :stack
|
5
|
+
attr_reader :kind, :msg, :stack, :suppression
|
6
6
|
|
7
7
|
def initialize(configuration, error)
|
8
8
|
@kind = error.at_xpath("kind").content
|
@@ -14,6 +14,7 @@ module RubyMemcheck
|
|
14
14
|
end
|
15
15
|
@stack = Stack.new(configuration, error.at_xpath("stack"))
|
16
16
|
@configuration = configuration
|
17
|
+
@suppression = Suppression.new(configuration, error.at_xpath("suppression"))
|
17
18
|
end
|
18
19
|
|
19
20
|
def skip?
|
@@ -34,6 +35,7 @@ module RubyMemcheck
|
|
34
35
|
" #{frame}\n"
|
35
36
|
end
|
36
37
|
end
|
38
|
+
str << suppression.to_s
|
37
39
|
str.string
|
38
40
|
end
|
39
41
|
|
data/lib/ruby_memcheck.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "tempfile"
|
4
|
-
require "nokogiri"
|
5
4
|
require "rake/testtask"
|
6
5
|
|
7
6
|
require "ruby_memcheck/configuration"
|
@@ -9,6 +8,7 @@ require "ruby_memcheck/frame"
|
|
9
8
|
require "ruby_memcheck/stack"
|
10
9
|
require "ruby_memcheck/test_task"
|
11
10
|
require "ruby_memcheck/valgrind_error"
|
11
|
+
require "ruby_memcheck/suppression"
|
12
12
|
require "ruby_memcheck/version"
|
13
13
|
|
14
14
|
module RubyMemcheck
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_memcheck
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Zhu
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -94,7 +94,7 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '2.3'
|
97
|
-
description:
|
97
|
+
description:
|
98
98
|
email:
|
99
99
|
- peter@peterzhu.ca
|
100
100
|
executables: []
|
@@ -113,6 +113,7 @@ files:
|
|
113
113
|
- lib/ruby_memcheck/configuration.rb
|
114
114
|
- lib/ruby_memcheck/frame.rb
|
115
115
|
- lib/ruby_memcheck/stack.rb
|
116
|
+
- lib/ruby_memcheck/suppression.rb
|
116
117
|
- lib/ruby_memcheck/test_task.rb
|
117
118
|
- lib/ruby_memcheck/valgrind_error.rb
|
118
119
|
- lib/ruby_memcheck/version.rb
|
@@ -122,7 +123,7 @@ licenses:
|
|
122
123
|
- MIT
|
123
124
|
metadata:
|
124
125
|
homepage_uri: https://github.com/peterzhu2118/ruby_memcheck
|
125
|
-
post_install_message:
|
126
|
+
post_install_message:
|
126
127
|
rdoc_options: []
|
127
128
|
require_paths:
|
128
129
|
- lib
|
@@ -137,8 +138,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
138
|
- !ruby/object:Gem::Version
|
138
139
|
version: '0'
|
139
140
|
requirements: []
|
140
|
-
rubygems_version: 3.
|
141
|
-
signing_key:
|
141
|
+
rubygems_version: 3.3.0.dev
|
142
|
+
signing_key:
|
142
143
|
specification_version: 4
|
143
144
|
summary: Use Valgrind memcheck without going crazy
|
144
145
|
test_files: []
|