ruby_memcheck 1.0.0 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 751718a23aee213973e93656dba653e4e253fd3f83618007c39e809827273ac5
4
- data.tar.gz: 55d6196fb48e0c18fabb5c87536c2c4114d7a1c1a2b04128ec2c707389934de0
3
+ metadata.gz: c5872b7150e47c3eb369c82bff0f8adbd58e48ecf69cdd2c41f7aee2e11d2591
4
+ data.tar.gz: eb72ad63ada1c5af40938059f25f6392d30b44262d2482fc836aac795673683c
5
5
  SHA512:
6
- metadata.gz: 861d0639b3d06d124f4020cb372472954018ad113ba4864b9367be6c6d167a338297d18c7c4adbcae767ba4a30e8925402bd7faa5a97841a513914ce41e10997
7
- data.tar.gz: e0dc1e236947746baef93281f00ec8129f651b7e560e56d2dffc5c188f14e5b32b39adc204ecea2da51c1e9ed341f1c00ff55b4b82521bb2b7b54085d5bfddfc
6
+ metadata.gz: 0b6582216142426fb20ebbad4493b0002f83aa3696ec314cf8173890eba2cc1398fcf89d7227a629e7be3f642f60551b315cc9957df47f17e0d603fa406b1a43
7
+ data.tar.gz: 74739f350aa890ef955fdc8d63c40810f8997ef4aaf8b5c5763086787da22efadf243e1a5e9d2ea20ac672714c1aed20bc72df9ab9a8abd22c7b3c9244114c59
@@ -6,9 +6,9 @@ jobs:
6
6
  strategy:
7
7
  matrix:
8
8
  entry:
9
- - { ruby: '2.6', allowed-failure: false }
10
9
  - { ruby: '2.7', allowed-failure: false }
11
10
  - { ruby: '3.0', allowed-failure: false }
11
+ - { ruby: '3.1', allowed-failure: false }
12
12
  - { ruby: ruby-head, allowed-failure: false }
13
13
  name: ruby ${{ matrix.entry.ruby }}
14
14
  steps:
data/.rubocop.yml CHANGED
@@ -8,3 +8,6 @@ AllCops:
8
8
  Style/GlobalVars:
9
9
  Exclude:
10
10
  - test/ruby_memcheck/ext/extconf.rb
11
+
12
+ Layout/CommentIndentation:
13
+ AllowForAlignment: true
data/README.md CHANGED
@@ -26,16 +26,19 @@ Only gems with native extensions can use this gem. If your gem is written in pla
26
26
 
27
27
  This gem runs Valgrind with the `--xml` option to generate an XML of all the errors. It will then parse the XML and use various heuristics based on the type of the error and the stack trace to filter out errors that are false positives.
28
28
 
29
+ For more details, read [this blog post](https://blog.peterzhu.ca/ruby-memcheck/).
30
+
29
31
  ### Limitations
30
32
 
31
33
  Because of the aggressive heuristics used to filter out false positives, there are various limitations of what this gem can detect.
32
34
 
33
35
  1. This gem is only expected to work on Linux.
36
+ 1. This gem runs your gem's test suite to find errors and memory leaks. It will only be able to report errors on code paths that are covered by your tests. So make sure your test suite has good coverage!
34
37
  1. It will not find memory leaks in Ruby. It filters out everything in Ruby.
35
38
  1. It will not find memory leaks of allocations that occurred in Ruby (even if the memory leak is caused by your native extension).
36
39
 
37
40
  An example of this is if a string is allocated in Ruby, passed into your native extension, you change the pointer of the string without freeing the contents, so the contents of the string becomes leaked.
38
- 1. To filter out false-positives, it will only find definite leaks (i.e. memory regions with no pointers to it). It will not find possible leaks (i.e. memory regions with pointers to it).
41
+ 1. To filter out false positives, it will only find definite leaks (i.e. memory regions with no pointers to it). It will not find possible leaks (i.e. memory regions with pointers to it).
39
42
  1. It will not find leaks that occur in the `Init` function of your native extension.
40
43
  1. It will not find uses of undefined values (e.g. conditional jumps depending on undefined values). This is just a technical limitation that has not been solved yet (contributions welcome!).
41
44
 
@@ -67,6 +70,7 @@ The easiest way to use this gem is to use it on your test suite (minitest or RSp
67
70
  ```ruby
68
71
  RubyMemcheck.config(binary_name: "your_binary_name")
69
72
  ```
73
+
70
74
  1. Setup the test task for your test framework.
71
75
  - **minitest**
72
76
 
@@ -117,6 +121,18 @@ The easiest way to use this gem is to use it on your test suite (minitest or RSp
117
121
  end
118
122
  ```
119
123
 
124
+ 1. Add the following line to your `test_helper.rb` or `spec_helper.rb`:
125
+
126
+ ```ruby
127
+ at_exit { GC.start }
128
+ ```
129
+
130
+ This will run a major garbage collection cycle before the Ruby process shuts down. This will ensure that any remaining Ruby objects are collected which will prevent Valgrind from reporting false positives.
131
+
132
+ It is safest to add the line above at the very first line of `test_helper.rb` or `spec_helper.rb`.
133
+
134
+ - **For minitest:** It is important that the line above is added BEFORE the `require "minitest/autorun"` line.
135
+
120
136
  1. You're ready to run your test suite with Valgrind using `rake test:valgrind` or `rake spec:valgrind`! Note that this will take a while to run because Valgrind will make Ruby significantly slower.
121
137
  1. (Optional) If you find false positives in the output, you can create Valgrind suppression files. See the [`Suppression files`](#suppression-files) section for more details.
122
138
 
@@ -29,6 +29,8 @@ module RubyMemcheck
29
29
  /\Arb_respond_to\z/,
30
30
  /\Arb_thread_create\z/, # Threads are relased to a cache, so they may be reported as a leak
31
31
  /\Arb_yield/,
32
+ /\Astack_chunk_alloc/, # Remove this after Ruby 2.7.7, 3.0.5, 3.1.3 are relased
33
+ # See: https://github.com/Shopify/ruby_memcheck/issues/6
32
34
  ].freeze
33
35
 
34
36
  attr_reader :binary_name, :ruby, :valgrind, :valgrind_options, :valgrind_suppressions_dir,
@@ -71,6 +73,13 @@ module RubyMemcheck
71
73
 
72
74
  def command(*args)
73
75
  [
76
+ # On some Rubies, not setting the stack size to be ulimited causes
77
+ # Valgrind to report the following error:
78
+ # Invalid write of size 1
79
+ # reserve_stack (thread_pthread.c:845)
80
+ # ruby_init_stack (thread_pthread.c:871)
81
+ # main (main.c:48)
82
+ "ulimit -s unlimited && ",
74
83
  valgrind,
75
84
  valgrind_options,
76
85
  get_valgrind_suppression_files(valgrind_suppressions_dir).map { |f| "--suppressions=#{f}" },
@@ -10,8 +10,9 @@ module RubyMemcheck
10
10
 
11
11
  def report_valgrind_errors
12
12
  if configuration.valgrind_xml_dir
13
- parse_valgrind_output
14
- remove_valgrind_xml_files
13
+ xml_files = valgrind_xml_files
14
+ parse_valgrind_output(xml_files)
15
+ remove_valgrind_xml_files(xml_files)
15
16
 
16
17
  unless errors.empty?
17
18
  output_valgrind_errors
@@ -20,31 +21,39 @@ module RubyMemcheck
20
21
  end
21
22
  end
22
23
 
23
- def parse_valgrind_output
24
+ def valgrind_xml_files
25
+ Dir[File.join(configuration.valgrind_xml_dir, "*")]
26
+ end
27
+
28
+ def parse_valgrind_output(xml_files)
24
29
  require "nokogiri"
25
30
 
26
31
  @errors = []
27
32
 
28
- Dir[File.join(configuration.valgrind_xml_dir, "*")].each do |file|
33
+ xml_files.each do |file|
29
34
  Nokogiri::XML::Reader(File.open(file)).each do |node|
30
35
  next unless node.name == "error" && node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
36
+
31
37
  error_xml = Nokogiri::XML::Document.parse(node.outer_xml).root
32
38
  error = ValgrindError.new(configuration, error_xml)
33
39
  next if error.skip?
40
+
34
41
  @errors << error
35
42
  end
36
43
  end
37
44
  end
38
45
 
46
+ def remove_valgrind_xml_files(xml_files)
47
+ xml_files.each do |file|
48
+ File.delete(file)
49
+ end
50
+ end
51
+
39
52
  def output_valgrind_errors
40
53
  @errors.each do |error|
41
54
  configuration.output_io.puts error
42
55
  configuration.output_io.puts
43
56
  end
44
57
  end
45
-
46
- def remove_valgrind_xml_files
47
- FileUtils.rm_rf(configuration.valgrind_xml_dir)
48
- end
49
58
  end
50
59
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyMemcheck
4
- VERSION = "1.0.0"
4
+ VERSION = "1.0.3"
5
5
  end
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: 1.0.0
4
+ version: 1.0.3
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-11-03 00:00:00.000000000 Z
11
+ date: 2022-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -122,7 +122,7 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '2.3'
125
- description:
125
+ description:
126
126
  email:
127
127
  - peter@peterzhu.ca
128
128
  executables: []
@@ -153,7 +153,7 @@ licenses:
153
153
  - MIT
154
154
  metadata:
155
155
  homepage_uri: https://github.com/peterzhu2118/ruby_memcheck
156
- post_install_message:
156
+ post_install_message:
157
157
  rdoc_options: []
158
158
  require_paths:
159
159
  - lib
@@ -168,8 +168,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
168
  - !ruby/object:Gem::Version
169
169
  version: '0'
170
170
  requirements: []
171
- rubygems_version: 3.2.22
172
- signing_key:
171
+ rubygems_version: 3.3.7
172
+ signing_key:
173
173
  specification_version: 4
174
174
  summary: Use Valgrind memcheck without going crazy
175
175
  test_files: []