living_dead 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +108 -0
- data/Rakefile +17 -0
- data/changelog.md +5 -0
- data/ext/living_dead/extconf.rb +2 -0
- data/ext/living_dead/living_dead.c +217 -0
- data/lib/living_dead.rb +96 -0
- data/lib/living_dead/version.rb +3 -0
- data/living_dead.gemspec +28 -0
- data/scratch.rb +20 -0
- data/spec/fixtures/singleton_class/in_class.rb +24 -0
- data/spec/fixtures/singleton_class/in_proc.rb +23 -0
- data/spec/fixtures/singleton_class/method_in_proc.rb +21 -0
- data/spec/fixtures/singleton_class/retained.rb +20 -0
- data/spec/fixtures/singleton_class/simple.rb +21 -0
- data/spec/fixtures/singleton_class_instance_eval/in_class.rb +24 -0
- data/spec/fixtures/singleton_class_instance_eval/in_proc.rb +24 -0
- data/spec/fixtures/singleton_class_instance_eval/method_in_proc.rb +22 -0
- data/spec/fixtures/singleton_class_instance_eval/retained.rb +21 -0
- data/spec/fixtures/singleton_class_instance_eval/simple.rb +22 -0
- data/spec/fixtures/string/not_retained.rb +19 -0
- data/spec/fixtures/string/retained.rb +19 -0
- data/spec/fixtures/string/string_in_class.rb +22 -0
- data/spec/fixtures/string/string_in_proc.rb +21 -0
- data/spec/fixtures/string/string_method_in_proc.rb +20 -0
- data/spec/fixtures/times_map/in_class.rb +24 -0
- data/spec/fixtures/times_map/in_proc.rb +25 -0
- data/spec/fixtures/times_map/method_in_proc.rb +22 -0
- data/spec/fixtures/times_map/retained.rb +22 -0
- data/spec/fixtures/times_map/simple.rb +22 -0
- data/spec/living_dead/singleton_class_instance_eval_spec.rb +30 -0
- data/spec/living_dead/singleton_class_spec.rb +30 -0
- data/spec/living_dead/string_spec.rb +24 -0
- data/spec/living_dead/times_map_spec.rb +30 -0
- data/spec/living_dead_spec.rb +24 -0
- data/spec/spec_helper.rb +28 -0
- metadata +168 -0
data/living_dead.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'living_dead/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "living_dead"
|
8
|
+
spec.version = LivingDead::VERSION
|
9
|
+
spec.authors = ["Richard Schneeman"]
|
10
|
+
spec.email = ["richard.schneeman+rubygems@gmail.com"]
|
11
|
+
spec.summary = %q{LivingDead traces objects to see if they are retained or freed by MRI}
|
12
|
+
spec.description = %q{LivingDead traces objects to see if they are retained or freed by MRI}
|
13
|
+
spec.homepage = "https://github.com/schneems/living_dead"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.extensions = %w[ext/living_dead/extconf.rb]
|
17
|
+
spec.required_ruby_version = '>= 2.1.0'
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0")
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "rake-compiler"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
end
|
data/scratch.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../lib")))
|
2
|
+
|
3
|
+
load File.expand_path(File.join(__FILE__, "../lib/living_dead.rb"))
|
4
|
+
|
5
|
+
def run
|
6
|
+
obj = Object.new
|
7
|
+
LivingDead.trace(obj)
|
8
|
+
|
9
|
+
|
10
|
+
return obj
|
11
|
+
end
|
12
|
+
|
13
|
+
retained_here = run
|
14
|
+
|
15
|
+
|
16
|
+
puts LivingDead.tracing_hash
|
17
|
+
puts LivingDead.freed_hash
|
18
|
+
|
19
|
+
puts LivingDead.traced_objects.inspect
|
20
|
+
puts LivingDead.freed_objects.inspect
|
@@ -0,0 +1,24 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
class Runner
|
6
|
+
|
7
|
+
def run
|
8
|
+
obj = Object.new
|
9
|
+
LivingDead.trace(obj)
|
10
|
+
obj.singleton_class
|
11
|
+
obj = nil
|
12
|
+
|
13
|
+
return nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Runner.new.run
|
18
|
+
|
19
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
20
|
+
|
21
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
22
|
+
actual = alive_count
|
23
|
+
result = expected == actual ? "PASS" : "FAIL"
|
24
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
-> {
|
7
|
+
obj = Object.new
|
8
|
+
LivingDead.trace(obj)
|
9
|
+
obj.singleton_class
|
10
|
+
obj = nil
|
11
|
+
}.call
|
12
|
+
|
13
|
+
return nil
|
14
|
+
end
|
15
|
+
|
16
|
+
run
|
17
|
+
|
18
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
19
|
+
|
20
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
21
|
+
actual = alive_count
|
22
|
+
result = expected == actual ? "PASS" : "FAIL"
|
23
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
obj = Object.new
|
7
|
+
LivingDead.trace(obj)
|
8
|
+
obj.singleton_class
|
9
|
+
obj = nil
|
10
|
+
|
11
|
+
return nil
|
12
|
+
end
|
13
|
+
|
14
|
+
-> { run }.call
|
15
|
+
|
16
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
17
|
+
|
18
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
19
|
+
actual = alive_count
|
20
|
+
result = expected == actual ? "PASS" : "FAIL"
|
21
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
@obj = Object.new
|
7
|
+
LivingDead.trace(@obj)
|
8
|
+
@obj.singleton_class
|
9
|
+
|
10
|
+
return nil
|
11
|
+
end
|
12
|
+
|
13
|
+
run
|
14
|
+
|
15
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
16
|
+
|
17
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 1)
|
18
|
+
actual = alive_count
|
19
|
+
result = expected == actual ? "PASS" : "FAIL"
|
20
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
obj = Object.new
|
7
|
+
LivingDead.trace(obj)
|
8
|
+
obj.singleton_class
|
9
|
+
obj = nil
|
10
|
+
|
11
|
+
return nil
|
12
|
+
end
|
13
|
+
|
14
|
+
run
|
15
|
+
|
16
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
17
|
+
|
18
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
19
|
+
actual = alive_count
|
20
|
+
result = expected == actual ? "PASS" : "FAIL"
|
21
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
class Runner
|
6
|
+
def run
|
7
|
+
obj = Object.new
|
8
|
+
LivingDead.trace(obj)
|
9
|
+
obj.singleton_class.instance_eval do
|
10
|
+
end
|
11
|
+
obj = nil
|
12
|
+
|
13
|
+
return nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Runner.new.run
|
18
|
+
|
19
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
20
|
+
|
21
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
22
|
+
actual = alive_count
|
23
|
+
result = expected == actual ? "PASS" : "FAIL"
|
24
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
-> {
|
7
|
+
obj = Object.new
|
8
|
+
LivingDead.trace(obj)
|
9
|
+
obj.singleton_class.instance_eval do
|
10
|
+
end
|
11
|
+
obj = nil
|
12
|
+
}.call
|
13
|
+
|
14
|
+
return nil
|
15
|
+
end
|
16
|
+
|
17
|
+
run
|
18
|
+
|
19
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
20
|
+
|
21
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
22
|
+
actual = alive_count
|
23
|
+
result = expected == actual ? "PASS" : "FAIL"
|
24
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
obj = Object.new
|
7
|
+
LivingDead.trace(obj)
|
8
|
+
obj.singleton_class.instance_eval do
|
9
|
+
end
|
10
|
+
obj = nil
|
11
|
+
|
12
|
+
return nil
|
13
|
+
end
|
14
|
+
|
15
|
+
-> { run }.call
|
16
|
+
|
17
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
18
|
+
|
19
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
20
|
+
actual = alive_count
|
21
|
+
result = expected == actual ? "PASS" : "FAIL"
|
22
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
@obj = Object.new
|
7
|
+
LivingDead.trace(@obj)
|
8
|
+
@obj.singleton_class.instance_eval do
|
9
|
+
end
|
10
|
+
|
11
|
+
return nil
|
12
|
+
end
|
13
|
+
|
14
|
+
run
|
15
|
+
|
16
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
17
|
+
|
18
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 1)
|
19
|
+
actual = alive_count
|
20
|
+
result = expected == actual ? "PASS" : "FAIL"
|
21
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
obj = Object.new
|
7
|
+
LivingDead.trace(obj)
|
8
|
+
obj.singleton_class.instance_eval do
|
9
|
+
end
|
10
|
+
obj = nil
|
11
|
+
|
12
|
+
return nil
|
13
|
+
end
|
14
|
+
|
15
|
+
run
|
16
|
+
|
17
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
18
|
+
|
19
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
20
|
+
actual = alive_count
|
21
|
+
result = expected == actual ? "PASS" : "FAIL"
|
22
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
string = ""
|
7
|
+
LivingDead.trace(string)
|
8
|
+
|
9
|
+
return nil
|
10
|
+
end
|
11
|
+
|
12
|
+
run
|
13
|
+
|
14
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
15
|
+
|
16
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
17
|
+
actual = alive_count
|
18
|
+
result = expected == actual ? "PASS" : "FAIL"
|
19
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
@string = ""
|
7
|
+
LivingDead.trace(@string)
|
8
|
+
|
9
|
+
return nil
|
10
|
+
end
|
11
|
+
|
12
|
+
run
|
13
|
+
|
14
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
15
|
+
|
16
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 1)
|
17
|
+
actual = alive_count
|
18
|
+
result = expected == actual ? "PASS" : "FAIL"
|
19
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
class Runner
|
6
|
+
def run
|
7
|
+
string = ""
|
8
|
+
LivingDead.trace(string)
|
9
|
+
string
|
10
|
+
|
11
|
+
return nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Runner.new.run
|
16
|
+
|
17
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
18
|
+
|
19
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
20
|
+
actual = alive_count
|
21
|
+
result = expected == actual ? "PASS" : "FAIL"
|
22
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
-> {
|
7
|
+
string = ""
|
8
|
+
LivingDead.trace(string)
|
9
|
+
string
|
10
|
+
}.call
|
11
|
+
return nil
|
12
|
+
end
|
13
|
+
|
14
|
+
run
|
15
|
+
|
16
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
17
|
+
|
18
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
19
|
+
actual = alive_count
|
20
|
+
result = expected == actual ? "PASS" : "FAIL"
|
21
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
string = ""
|
7
|
+
LivingDead.trace(string)
|
8
|
+
string
|
9
|
+
|
10
|
+
return nil
|
11
|
+
end
|
12
|
+
|
13
|
+
-> {run}.call
|
14
|
+
|
15
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
16
|
+
|
17
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
18
|
+
actual = alive_count
|
19
|
+
result = expected == actual ? "PASS" : "FAIL"
|
20
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
class Runner
|
6
|
+
def run
|
7
|
+
array = 1.times.map {
|
8
|
+
obj = Object.new
|
9
|
+
LivingDead.trace(obj)
|
10
|
+
obj
|
11
|
+
}
|
12
|
+
array = nil
|
13
|
+
return nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Runner.new.run
|
18
|
+
|
19
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
20
|
+
|
21
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
22
|
+
actual = alive_count
|
23
|
+
result = expected == actual ? "PASS" : "FAIL"
|
24
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "../../../../lib")))
|
2
|
+
|
3
|
+
require 'living_dead'
|
4
|
+
|
5
|
+
def run
|
6
|
+
-> {
|
7
|
+
array = 1.times.map {
|
8
|
+
obj = Object.new
|
9
|
+
LivingDead.trace(obj)
|
10
|
+
obj
|
11
|
+
}
|
12
|
+
array = nil
|
13
|
+
}.call
|
14
|
+
|
15
|
+
return nil
|
16
|
+
end
|
17
|
+
|
18
|
+
run
|
19
|
+
|
20
|
+
alive_count = LivingDead.traced_objects.select { |tracer| tracer.retained? }.length
|
21
|
+
|
22
|
+
expected = Integer(ENV["EXPECTED_OUT"] || 0)
|
23
|
+
actual = alive_count
|
24
|
+
result = expected == actual ? "PASS" : "FAIL"
|
25
|
+
puts "#{result}: expected: #{expected}, actual: #{actual}"
|