bleak_house 4.1.1 → 4.2
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.
- data/CHANGELOG +3 -1
- data/Manifest +3 -3
- data/README +9 -9
- data/Rakefile +4 -4
- data/TODO +2 -0
- data/bleak_house.gemspec +37 -98
- data/ext/build_ruby.rb +44 -41
- data/ext/extconf.rb +25 -2
- data/ext/snapshot.c +20 -20
- data/ext/snapshot.h +1 -1
- data/lib/bleak_house/analyzer.rb +12 -12
- data/lib/bleak_house/hook.rb +2 -4
- data/ruby/ruby-1.8.6-p286.tar.bz2 +0 -0
- data/ruby/{configure.patch → ruby.patch} +231 -9
- data/ruby/valgrind.patch +10 -10
- data/test/benchmark/bench.rb +1 -1
- data/test/unit/test_bleak_house.rb +7 -7
- data.tar.gz.sig +0 -0
- metadata +7 -8
- metadata.gz.sig +0 -0
- data/ruby/gc.patch +0 -129
- data/ruby/ruby-1.8.6-p230.tar.bz2 +0 -0
data/CHANGELOG
CHANGED
data/Manifest
CHANGED
@@ -11,10 +11,10 @@ lib/bleak_house.rb
|
|
11
11
|
LICENSE
|
12
12
|
LICENSE_BSD
|
13
13
|
Manifest
|
14
|
+
Rakefile
|
14
15
|
README
|
15
|
-
ruby/
|
16
|
-
ruby/
|
17
|
-
ruby/ruby-1.8.6-p230.tar.bz2
|
16
|
+
ruby/ruby-1.8.6-p286.tar.bz2
|
17
|
+
ruby/ruby.patch
|
18
18
|
ruby/valgrind.patch
|
19
19
|
test/benchmark/bench.rb
|
20
20
|
test/test_helper.rb
|
data/README
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
|
2
2
|
BleakHouse
|
3
3
|
|
4
|
-
A library for finding memory leaks.
|
4
|
+
A library for finding memory leaks.
|
5
5
|
|
6
6
|
== License
|
7
7
|
|
8
|
-
Copyright 2007, 2008 Cloudburst, LLC. Licensed under the AFL 3. See the included LICENSE file. Portions copyright 2006 Eric Hodel and used with permission. See the included LICENSE_BSD file.
|
8
|
+
Copyright 2007, 2008 Cloudburst, LLC. Licensed under the AFL 3. See the included LICENSE file. Portions copyright 2006 Eric Hodel and used with permission. See the included LICENSE_BSD file.
|
9
9
|
|
10
|
-
The public certificate for this gem is here[http://rubyforge.org/frs/download.php/25331/evan_weaver-original-public_cert.pem].
|
10
|
+
The public certificate for this gem is here[http://rubyforge.org/frs/download.php/25331/evan_weaver-original-public_cert.pem].
|
11
11
|
|
12
12
|
If you use this software, please {make a donation}[http://blog.evanweaver.com/donate/], or {recommend Evan}[http://www.workingwithrails.com/person/7739-evan-weaver] at Working with Rails.
|
13
13
|
|
@@ -43,10 +43,10 @@ First, to setup the app for profiling, add the following at the bottom of <tt>co
|
|
43
43
|
require 'bleak_house' if ENV['BLEAK_HOUSE']
|
44
44
|
|
45
45
|
Then, to engage the logger (possibly in a live deployment situation), start a server instance as so:
|
46
|
-
RAILS_ENV=production BLEAK_HOUSE=1 ruby-bleak-house ./script/server
|
46
|
+
RAILS_ENV=production BLEAK_HOUSE=1 ruby-bleak-house ./script/server
|
47
47
|
|
48
48
|
Look for the message:
|
49
|
-
** Bleakhouse: installed
|
49
|
+
** Bleakhouse: installed
|
50
50
|
|
51
51
|
Exercise your app. After a couple hundred requests, hit CTRL-C. The server will stop and BleakHouse will produce a dumpfile in <tt>/tmp</tt>:
|
52
52
|
|
@@ -68,10 +68,10 @@ To analyze it, just run the listed command. The top 20 leakiest lines will be li
|
|
68
68
|
935 /opt/local//lib/ruby/site_ruby/1.8/rubygems/specification.rb:557:String
|
69
69
|
834 /opt/local//lib/ruby/site_ruby/1.8/rubygems/version.rb:146:Array
|
70
70
|
...
|
71
|
-
|
71
|
+
|
72
72
|
You can pass an integer as the second parameter to <tt>bleak</tt> if you want to see more lines than the default.
|
73
73
|
|
74
|
-
The underscored types are special Ruby internal structs, but can be real leaks just as easily as fullblown classes.
|
74
|
+
The underscored types are special Ruby internal structs, but can be real leaks just as easily as fullblown classes.
|
75
75
|
|
76
76
|
= Extras
|
77
77
|
|
@@ -95,11 +95,11 @@ If BleakHouse doesn't report any heap growth but you still have memory growth, y
|
|
95
95
|
|
96
96
|
== Methods
|
97
97
|
|
98
|
-
The easiest way to fix a leak is to make it repeatable.
|
98
|
+
The easiest way to fix a leak is to make it repeatable.
|
99
99
|
|
100
100
|
First, write a script that exercises your app in a deterministic way. Run it for a small number of loops; then run <tt>bleak</tt>. Then run it for a larger number of loops, and run <tt>bleak</tt> again. The lines that grow significantly between runs are your leaks for that codepath.
|
101
101
|
|
102
|
-
Now, look at those lines in the source and try to figure out what references them. Where do the return values go? Add some breakpoints or output backtraces to <tt>STDERR</tt> as you go. Eventually you should find a point where it is relatively clear that a reference is getting maintained.
|
102
|
+
Now, look at those lines in the source and try to figure out what references them. Where do the return values go? Add some breakpoints or output backtraces to <tt>STDERR</tt> as you go. Eventually you should find a point where it is relatively clear that a reference is getting maintained.
|
103
103
|
|
104
104
|
Try to remove that reference, run your script again, and see if the object counts have dropped.
|
105
105
|
|
data/Rakefile
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
require 'echoe'
|
3
3
|
|
4
4
|
Echoe.new("bleak_house") do |p|
|
5
|
-
p.author = "Evan Weaver"
|
5
|
+
p.author = "Evan Weaver"
|
6
6
|
p.project = "fauna"
|
7
|
-
p.summary = "A library for finding memory leaks."
|
8
|
-
p.url = "http://blog.evanweaver.com/files/doc/fauna/bleak_house/"
|
7
|
+
p.summary = "A library for finding memory leaks."
|
8
|
+
p.url = "http://blog.evanweaver.com/files/doc/fauna/bleak_house/"
|
9
9
|
p.docs_host = 'blog.evanweaver.com:~/www/bax/public/files/doc/'
|
10
|
-
p.require_signed = true
|
10
|
+
p.require_signed = true
|
11
11
|
p.rdoc_pattern = /^ext.*\.c|lib.*|^README|^CHANGELOG|^TODO|^LICENSE|^COPYING$/
|
12
12
|
end
|
data/TODO
CHANGED
data/bleak_house.gemspec
CHANGED
@@ -1,101 +1,40 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
1
2
|
|
2
|
-
|
3
|
-
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{bleak_house}
|
5
|
+
s.version = "4.2"
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
version: "0"
|
26
|
-
version:
|
27
|
-
description: A library for finding memory leaks.
|
28
|
-
email: ""
|
29
|
-
executables:
|
30
|
-
- bleak
|
31
|
-
extensions:
|
32
|
-
- ext/extconf.rb
|
33
|
-
extra_rdoc_files:
|
34
|
-
- CHANGELOG
|
35
|
-
- ext/snapshot.c
|
36
|
-
- lib/bleak_house/analyzer.rb
|
37
|
-
- lib/bleak_house/hook.rb
|
38
|
-
- lib/bleak_house.rb
|
39
|
-
- LICENSE
|
40
|
-
- LICENSE_BSD
|
41
|
-
- README
|
42
|
-
- TODO
|
43
|
-
files:
|
44
|
-
- bin/bleak
|
45
|
-
- CHANGELOG
|
46
|
-
- ext/build_ruby.rb
|
47
|
-
- ext/build_snapshot.rb
|
48
|
-
- ext/extconf.rb
|
49
|
-
- ext/snapshot.c
|
50
|
-
- ext/snapshot.h
|
51
|
-
- lib/bleak_house/analyzer.rb
|
52
|
-
- lib/bleak_house/hook.rb
|
53
|
-
- lib/bleak_house.rb
|
54
|
-
- LICENSE
|
55
|
-
- LICENSE_BSD
|
56
|
-
- Manifest
|
57
|
-
- README
|
58
|
-
- ruby/configure.patch
|
59
|
-
- ruby/gc.patch
|
60
|
-
- ruby/ruby-1.8.6-p230.tar.bz2
|
61
|
-
- ruby/valgrind.patch
|
62
|
-
- test/benchmark/bench.rb
|
63
|
-
- test/test_helper.rb
|
64
|
-
- test/unit/test_bleak_house.rb
|
65
|
-
- TODO
|
66
|
-
- bleak_house.gemspec
|
67
|
-
- Rakefile
|
68
|
-
has_rdoc: true
|
69
|
-
homepage: http://blog.evanweaver.com/files/doc/fauna/bleak_house/
|
70
|
-
post_install_message:
|
71
|
-
rdoc_options:
|
72
|
-
- --line-numbers
|
73
|
-
- --inline-source
|
74
|
-
- --title
|
75
|
-
- Bleak_house
|
76
|
-
- --main
|
77
|
-
- README
|
78
|
-
require_paths:
|
79
|
-
- lib
|
80
|
-
- ext
|
81
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
-
requirements:
|
83
|
-
- - ">="
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: "0"
|
86
|
-
version:
|
87
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
-
requirements:
|
89
|
-
- - "="
|
90
|
-
- !ruby/object:Gem::Version
|
91
|
-
version: "1.2"
|
92
|
-
version:
|
93
|
-
requirements: []
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Evan Weaver"]
|
9
|
+
s.cert_chain = ["/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-public_cert.pem"]
|
10
|
+
s.date = %q{2009-02-20}
|
11
|
+
s.default_executable = %q{bleak}
|
12
|
+
s.description = %q{A library for finding memory leaks.}
|
13
|
+
s.email = %q{}
|
14
|
+
s.executables = ["bleak"]
|
15
|
+
s.extensions = ["ext/extconf.rb"]
|
16
|
+
s.extra_rdoc_files = ["CHANGELOG", "ext/snapshot.c", "lib/bleak_house/analyzer.rb", "lib/bleak_house/hook.rb", "lib/bleak_house.rb", "LICENSE", "LICENSE_BSD", "README", "TODO"]
|
17
|
+
s.files = ["bin/bleak", "CHANGELOG", "ext/build_ruby.rb", "ext/build_snapshot.rb", "ext/extconf.rb", "ext/snapshot.c", "ext/snapshot.h", "lib/bleak_house/analyzer.rb", "lib/bleak_house/hook.rb", "lib/bleak_house.rb", "LICENSE", "LICENSE_BSD", "Manifest", "Rakefile", "README", "ruby/ruby-1.8.6-p286.tar.bz2", "ruby/ruby.patch", "ruby/valgrind.patch", "test/benchmark/bench.rb", "test/test_helper.rb", "test/unit/test_bleak_house.rb", "TODO", "bleak_house.gemspec"]
|
18
|
+
s.has_rdoc = true
|
19
|
+
s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/bleak_house/}
|
20
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Bleak_house", "--main", "README"]
|
21
|
+
s.require_paths = ["lib", "ext"]
|
22
|
+
s.rubyforge_project = %q{fauna}
|
23
|
+
s.rubygems_version = %q{1.3.1}
|
24
|
+
s.signing_key = %q{/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-private_key.pem}
|
25
|
+
s.summary = %q{A library for finding memory leaks.}
|
26
|
+
s.test_files = ["test/test_helper.rb", "test/unit/test_bleak_house.rb"]
|
94
27
|
|
95
|
-
|
96
|
-
|
97
|
-
specification_version
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
28
|
+
if s.respond_to? :specification_version then
|
29
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
30
|
+
s.specification_version = 2
|
31
|
+
|
32
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
33
|
+
s.add_development_dependency(%q<echoe>, [">= 0"])
|
34
|
+
else
|
35
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
36
|
+
end
|
37
|
+
else
|
38
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
39
|
+
end
|
40
|
+
end
|
data/ext/build_ruby.rb
CHANGED
@@ -15,58 +15,63 @@ tmp = "/tmp/"
|
|
15
15
|
require 'fileutils'
|
16
16
|
require 'rbconfig'
|
17
17
|
|
18
|
+
def execute(command)
|
19
|
+
unless system(command)
|
20
|
+
puts "Failed: #{command.inspect}"
|
21
|
+
exit -1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
18
25
|
def which(basename)
|
19
|
-
#
|
26
|
+
# execute('which') is not compatible across Linux and BSD
|
20
27
|
ENV['PATH'].split(File::PATH_SEPARATOR).detect do |directory|
|
21
28
|
path = File.join(directory, basename.to_s)
|
22
29
|
path if File.exist? path
|
23
30
|
end
|
24
31
|
end
|
25
32
|
|
26
|
-
if which('ruby-bleak-house') and
|
27
|
-
`ruby-bleak-house -e "puts RUBY_PATCHLEVEL"`.to_i >=
|
28
|
-
#
|
33
|
+
if which('ruby-bleak-house') and
|
34
|
+
(patchlevel = `ruby-bleak-house -e "puts RUBY_PATCHLEVEL"`.to_i) >= 903
|
35
|
+
puts "Binary `ruby-bleak-house` is already available (patchlevel #{patchlevel})"
|
29
36
|
else
|
30
|
-
# Build
|
37
|
+
# Build
|
31
38
|
Dir.chdir(tmp) do
|
32
39
|
build_dir = "bleak_house"
|
33
40
|
binary_dir = File.dirname(`which ruby`)
|
34
|
-
|
41
|
+
|
35
42
|
FileUtils.rm_rf(build_dir) rescue nil
|
36
43
|
if File.exist? build_dir
|
37
44
|
raise "Could not delete previous build dir #{Dir.pwd}/#{build_dir}"
|
38
45
|
end
|
39
|
-
|
46
|
+
|
40
47
|
Dir.mkdir(build_dir)
|
41
|
-
|
48
|
+
|
42
49
|
begin
|
43
50
|
Dir.chdir(build_dir) do
|
44
|
-
|
45
|
-
|
46
|
-
bz2 = "ruby-1.8.6-
|
51
|
+
|
52
|
+
puts "Copy Ruby source"
|
53
|
+
bz2 = "ruby-1.8.6-p286.tar.bz2"
|
47
54
|
FileUtils.copy "#{source_dir}/#{bz2}", bz2
|
48
|
-
|
49
|
-
|
50
|
-
|
55
|
+
|
56
|
+
puts "Extract"
|
57
|
+
execute("tar xjf #{bz2}")
|
51
58
|
File.delete bz2
|
52
|
-
|
53
|
-
Dir.chdir("ruby-1.8.6-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
# Patch the makefile for arch/sitedir
|
59
|
+
|
60
|
+
Dir.chdir("ruby-1.8.6-p286") do
|
61
|
+
|
62
|
+
puts "Patch, configure, and build"
|
63
|
+
execute("patch -p0 < \'#{source_dir}/ruby.patch\'")
|
64
|
+
|
65
|
+
execute("./configure --prefix=#{binary_dir[0..-5]}") # --with-static-linked-ext
|
66
|
+
|
67
|
+
puts "Patch the makefile for arch/sitedir"
|
63
68
|
makefile = File.read('Makefile')
|
64
69
|
%w{arch sitearch sitedir}.each do | key |
|
65
70
|
makefile.gsub!(/#{key} = .*/, "#{key} = #{Config::CONFIG[key]}")
|
66
71
|
end
|
67
72
|
File.open('Makefile', 'w'){|f| f.puts(makefile)}
|
68
|
-
|
69
|
-
|
73
|
+
|
74
|
+
puts "Patch the config.h for constants"
|
70
75
|
constants = {
|
71
76
|
'RUBY_LIB' => 'rubylibdir', #define RUBY_LIB "/usr/lib/ruby/1.8"
|
72
77
|
'RUBY_SITE_LIB' => 'sitedir', #define RUBY_SITE_LIB "/usr/lib/ruby/site_ruby"
|
@@ -80,27 +85,25 @@ else
|
|
80
85
|
config_h.gsub!(/#define #{const} .*/, "#define #{const} \"#{Config::CONFIG[key]}\"")
|
81
86
|
end
|
82
87
|
File.open('config.h', 'w'){|f| f.puts(config_h)}
|
83
|
-
|
84
|
-
|
85
|
-
|
88
|
+
|
89
|
+
execute("make")
|
90
|
+
|
86
91
|
binary = "#{binary_dir}/ruby-bleak-house"
|
87
|
-
|
88
|
-
|
89
|
-
if File.exist? "ruby"
|
92
|
+
|
93
|
+
puts "Install binary"
|
94
|
+
if File.exist? "ruby"
|
90
95
|
# Avoid "Text file busy" error
|
91
96
|
File.delete binary if File.exist? binary
|
92
97
|
exec("cp ./ruby #{binary}; chmod 755 #{binary}")
|
93
98
|
else
|
94
|
-
raise
|
99
|
+
raise
|
95
100
|
end
|
96
101
|
end
|
97
|
-
|
102
|
+
|
98
103
|
end
|
99
|
-
rescue Object => e
|
100
|
-
raise "Please see the last modified log file in #{tmp}#{build_dir}, perhaps\nit will contain a clue.\n#{e.to_s}"
|
101
104
|
end
|
102
|
-
|
103
|
-
|
104
|
-
end
|
105
|
-
|
105
|
+
|
106
|
+
puts "Success"
|
107
|
+
end
|
108
|
+
|
106
109
|
end
|
data/ext/extconf.rb
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
require 'fileutils'
|
1
2
|
|
2
|
-
|
3
|
-
|
3
|
+
module BleakHouse
|
4
|
+
|
5
|
+
LOGDIR = File.expand_path('../../log', __FILE__)
|
6
|
+
LOGFILE = File.join(LOGDIR, 'bleak_house.log')
|
7
|
+
|
8
|
+
FileUtils.mkdir_p(LOGDIR)
|
9
|
+
|
10
|
+
def self.write_to_log(message)
|
11
|
+
File.open(LOGFILE, 'a') { |f| f.puts message }
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.execute(command)
|
15
|
+
unless system(command)
|
16
|
+
puts File.open(LOGFILE).read
|
17
|
+
exit -1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
BleakHouse.write_to_log('-%{ BUILDING RUBY }%-')
|
23
|
+
BleakHouse.execute("ruby build_ruby.rb >> #{BleakHouse::LOGFILE} 2>&1")
|
24
|
+
|
25
|
+
BleakHouse.write_to_log('-%{ BUILDING SNAPSHOT }%-')
|
26
|
+
BleakHouse.execute("ruby-bleak-house build_snapshot.rb >> #{BleakHouse::LOGFILE} 2>&1")
|
data/ext/snapshot.c
CHANGED
@@ -19,8 +19,8 @@ static VALUE snapshot(VALUE self, VALUE _logfile) {
|
|
19
19
|
Check_Type(_logfile, T_STRING);
|
20
20
|
|
21
21
|
RVALUE *obj, *obj_end;
|
22
|
-
st_table_entry *sym;
|
23
|
-
|
22
|
+
st_table_entry *sym;
|
23
|
+
|
24
24
|
struct heaps_slot * heaps = rb_gc_heap_slots();
|
25
25
|
struct st_table * sym_tbl = rb_parse_sym_tbl();
|
26
26
|
|
@@ -37,15 +37,15 @@ static VALUE snapshot(VALUE self, VALUE _logfile) {
|
|
37
37
|
int filled_slots = 0;
|
38
38
|
int free_slots = 0;
|
39
39
|
|
40
|
-
int i;
|
40
|
+
int i;
|
41
41
|
char * chr;
|
42
|
-
|
42
|
+
|
43
43
|
for (i = 0; i < 3; i++) {
|
44
44
|
/* request GC run */
|
45
45
|
rb_funcall(rb_mGC, rb_intern("start"), 0);
|
46
46
|
rb_thread_schedule();
|
47
47
|
}
|
48
|
-
|
48
|
+
|
49
49
|
/* walk the heap */
|
50
50
|
for (i = 0; i < rb_gc_heaps_used(); i++) {
|
51
51
|
obj = heaps[i].slot;
|
@@ -53,27 +53,27 @@ static VALUE snapshot(VALUE self, VALUE _logfile) {
|
|
53
53
|
for (; obj < obj_end; obj++) {
|
54
54
|
if (obj->as.basic.flags) { /* always 0 for freed objects */
|
55
55
|
filled_slots ++;
|
56
|
-
|
56
|
+
|
57
57
|
/* write the source file*/
|
58
58
|
if (obj->file) {
|
59
|
-
chr = obj->file;
|
59
|
+
chr = obj->file;
|
60
60
|
if (*chr != '\0') {
|
61
61
|
fprintf(logfile, "%s", obj->file);
|
62
62
|
} else {
|
63
|
-
fprintf(logfile, "__empty__");
|
63
|
+
fprintf(logfile, "__empty__");
|
64
64
|
}
|
65
65
|
} else {
|
66
66
|
fprintf(logfile, "__null__");
|
67
67
|
}
|
68
|
-
|
68
|
+
|
69
69
|
/* write the source line */
|
70
|
-
fprintf(logfile, ":");
|
70
|
+
fprintf(logfile, ":");
|
71
71
|
if (obj->line) {
|
72
72
|
fprintf(logfile, "%i", obj->line);
|
73
73
|
} else {
|
74
74
|
fprintf(logfile, "__null__");
|
75
75
|
}
|
76
|
-
|
76
|
+
|
77
77
|
/* write the class */
|
78
78
|
fprintf(logfile, ":");
|
79
79
|
switch (TYPE(obj)) {
|
@@ -96,7 +96,7 @@ static VALUE snapshot(VALUE self, VALUE _logfile) {
|
|
96
96
|
fprintf(logfile, rb_obj_classname((VALUE)obj));
|
97
97
|
}
|
98
98
|
}
|
99
|
-
|
99
|
+
|
100
100
|
/* write newline */
|
101
101
|
fprintf(logfile, "\n");
|
102
102
|
} else {
|
@@ -104,30 +104,30 @@ static VALUE snapshot(VALUE self, VALUE _logfile) {
|
|
104
104
|
}
|
105
105
|
}
|
106
106
|
}
|
107
|
-
|
108
|
-
/* walk the symbol table */
|
107
|
+
|
108
|
+
/* walk the symbol table */
|
109
109
|
/* hashed = lookup_builtin("Symbol");
|
110
110
|
for (i = 0; i < sym_tbl->num_bins; i++) {
|
111
111
|
for (sym = sym_tbl->bins[i]; sym != 0; sym = sym->next) {
|
112
112
|
fprintf(logfile, "%i,%lu\n", hashed + 1, sym->record);
|
113
113
|
}
|
114
114
|
} */
|
115
|
-
|
115
|
+
|
116
116
|
fprintf(logfile, "%i filled\n", filled_slots);
|
117
117
|
fprintf(logfile, "%i free\n", free_slots);
|
118
118
|
fclose(logfile);
|
119
|
-
|
119
|
+
|
120
120
|
return Qnil;
|
121
121
|
}
|
122
122
|
|
123
123
|
|
124
124
|
/*
|
125
125
|
|
126
|
-
This class performs the actual object logging of BleakHouse. To use it directly, you need to make calls to BleakHouse.snapshot.
|
126
|
+
This class performs the actual object logging of BleakHouse. To use it directly, you need to make calls to BleakHouse.snapshot.
|
127
127
|
|
128
|
-
By default, BleakHouse records a snapshot on exit. You can disable this by setting the environment variable <tt>NO_EXIT_HANDLER</tt> before startup.
|
128
|
+
By default, BleakHouse records a snapshot on exit. You can disable this by setting the environment variable <tt>NO_EXIT_HANDLER</tt> before startup.
|
129
129
|
|
130
|
-
It is also possible to externally trigger the snapshot at any time by sending <tt>SIGUSR2</tt> to the process.
|
130
|
+
It is also possible to externally trigger the snapshot at any time by sending <tt>SIGUSR2</tt> to the process.
|
131
131
|
|
132
132
|
== Example
|
133
133
|
|
@@ -138,7 +138,7 @@ At the start of your app, put:
|
|
138
138
|
|
139
139
|
Run your app. Once it exits, analyze your data:
|
140
140
|
bleak /path/to/logfile
|
141
|
-
|
141
|
+
|
142
142
|
*/
|
143
143
|
void
|
144
144
|
Init_snapshot()
|
data/ext/snapshot.h
CHANGED
data/lib/bleak_house/analyzer.rb
CHANGED
@@ -7,31 +7,31 @@ module BleakHouse
|
|
7
7
|
lines = args.last[/^\d+$/] ? args.pop.to_i : 20
|
8
8
|
|
9
9
|
raise "Can't diff more than 2 files" if args.size > 2
|
10
|
-
|
11
|
-
outputs = args.map do |file|
|
10
|
+
|
11
|
+
outputs = args.map do |file|
|
12
12
|
filled, free = `tail -n 2 #{file}`.split("\n")
|
13
13
|
unless filled =~ /filled/ and free =~ /free/
|
14
14
|
raise "#{file} is incomplete or corrupted"
|
15
15
|
end
|
16
|
-
|
17
|
-
length = `wc #{file}`.to_i - 2
|
18
|
-
cmd = ENV['NO_TRACE'] ? "awk -F: '{print $3}' " + file : "cat #{file}"
|
16
|
+
|
17
|
+
length = `wc #{file}`.to_i - 2
|
18
|
+
cmd = ENV['NO_TRACE'] ? "awk -F: '{print $3}' " + file : "cat #{file}"
|
19
19
|
cmd += " | sort | uniq -c | sort -nr | head -#{lines}"
|
20
|
-
|
20
|
+
|
21
21
|
["#{length} total objects", "#{filled} heap slots", "#{free} heap slots"] + `#{cmd}`.split("\n")
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
if outputs.size == 1
|
25
25
|
# Just output the data
|
26
|
-
puts "Displaying top #{lines} most common line/class pairs"
|
26
|
+
puts "Displaying top #{lines} most common line/class pairs"
|
27
27
|
puts outputs.first
|
28
28
|
else
|
29
|
-
puts "Displaying change in top #{lines} most common line/class pairs"
|
29
|
+
puts "Displaying change in top #{lines} most common line/class pairs"
|
30
30
|
puts diff(outputs)
|
31
31
|
end
|
32
32
|
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
def self.diff(outputs)
|
36
36
|
# Calculate the diff
|
37
37
|
diff = Hash.new(0)
|
@@ -47,8 +47,8 @@ module BleakHouse
|
|
47
47
|
-value
|
48
48
|
end.map do |key, value|
|
49
49
|
"#{value.to_s.rjust(6)} #{key}"
|
50
|
-
end
|
50
|
+
end
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
end
|
54
54
|
end
|
data/lib/bleak_house/hook.rb
CHANGED
@@ -6,7 +6,7 @@ module BleakHouse
|
|
6
6
|
filename = "/tmp/bleak.#{Process.pid}.#{@count}.dump"
|
7
7
|
STDERR.puts "** BleakHouse: working..."
|
8
8
|
BleakHouse.snapshot(filename)
|
9
|
-
STDERR.puts "** BleakHouse: complete\n** Bleakhouse: Run 'bleak #{filename}' to analyze."
|
9
|
+
STDERR.puts "** BleakHouse: complete\n** Bleakhouse: Run 'bleak #{filename}' to analyze."
|
10
10
|
@count += 1
|
11
11
|
end
|
12
12
|
end
|
@@ -20,6 +20,4 @@ end
|
|
20
20
|
|
21
21
|
Kernel.trap("USR2") do
|
22
22
|
BleakHouse.hook
|
23
|
-
end
|
24
|
-
|
25
|
-
|
23
|
+
end
|
Binary file
|
@@ -1,7 +1,18 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
diff -u Makefile.in Makefile.in
|
2
|
+
--- Makefile.in 2009-02-20 17:55:35.000000000 -0800
|
3
|
+
+++ Makefile.in 2009-02-20 18:06:52.000000000 -0800
|
4
|
+
@@ -34,7 +34,7 @@
|
5
|
+
|
6
|
+
empty =
|
7
|
+
OUTFLAG = @OUTFLAG@$(empty)
|
8
|
+
-CFLAGS = @CFLAGS@ @XCFLAGS@ @ARCH_FLAG@
|
9
|
+
+CFLAGS = @CFLAGS@ @XCFLAGS@ @ARCH_FLAG@ @VALGRIND_CFLAGS@
|
10
|
+
CPPFLAGS = -I. -I$(srcdir) @CPPFLAGS@
|
11
|
+
LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@
|
12
|
+
EXTLDFLAGS =
|
13
|
+
diff -u configure configure
|
14
|
+
--- configure 2009-02-20 17:55:33.000000000 -0800
|
15
|
+
+++ configure 2009-02-20 18:06:58.000000000 -0800
|
5
16
|
@@ -720,6 +720,7 @@
|
6
17
|
ARCHFILE
|
7
18
|
RDOCTARGET
|
@@ -18,7 +29,7 @@ Index: configure
|
|
18
29
|
--disable-rpath embed run path into extension libraries.
|
19
30
|
--enable-shared build a shared library for Ruby.
|
20
31
|
--enable-install-doc build and install rdoc indexes during install
|
21
|
-
@@ -
|
32
|
+
@@ -12990,13 +12992,11 @@
|
22
33
|
cat confdefs.h >>conftest.$ac_ext
|
23
34
|
cat >>conftest.$ac_ext <<_ACEOF
|
24
35
|
/* end confdefs.h. */
|
@@ -34,7 +45,7 @@ Index: configure
|
|
34
45
|
;
|
35
46
|
return 0;
|
36
47
|
}
|
37
|
-
@@ -
|
48
|
+
@@ -13036,13 +13036,11 @@
|
38
49
|
cat >>conftest.$ac_ext <<_ACEOF
|
39
50
|
/* end confdefs.h. */
|
40
51
|
#define _LARGEFILE_SOURCE 1
|
@@ -50,7 +61,7 @@ Index: configure
|
|
50
61
|
;
|
51
62
|
return 0;
|
52
63
|
}
|
53
|
-
@@ -
|
64
|
+
@@ -16306,6 +16304,172 @@
|
54
65
|
fi
|
55
66
|
fi
|
56
67
|
|
@@ -223,7 +234,7 @@ Index: configure
|
|
223
234
|
DEFAULT_KCODE="KCODE_NONE"
|
224
235
|
|
225
236
|
|
226
|
-
@@ -
|
237
|
+
@@ -18386,6 +18550,7 @@
|
227
238
|
ARCHFILE!$ARCHFILE$ac_delim
|
228
239
|
RDOCTARGET!$RDOCTARGET$ac_delim
|
229
240
|
XCFLAGS!$XCFLAGS$ac_delim
|
@@ -231,7 +242,7 @@ Index: configure
|
|
231
242
|
XLDFLAGS!$XLDFLAGS$ac_delim
|
232
243
|
LIBRUBY_LDSHARED!$LIBRUBY_LDSHARED$ac_delim
|
233
244
|
LIBRUBY_DLDFLAGS!$LIBRUBY_DLDFLAGS$ac_delim
|
234
|
-
@@ -
|
245
|
+
@@ -18419,7 +18584,7 @@
|
235
246
|
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
236
247
|
_ACEOF
|
237
248
|
|
@@ -240,3 +251,214 @@ Index: configure
|
|
240
251
|
break
|
241
252
|
elif $ac_last_try; then
|
242
253
|
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
254
|
+
diff -u configure.in configure.in
|
255
|
+
--- configure.in 2009-02-20 17:55:33.000000000 -0800
|
256
|
+
+++ configure.in 2009-02-20 18:06:52.000000000 -0800
|
257
|
+
@@ -956,6 +956,22 @@
|
258
|
+
fi
|
259
|
+
fi
|
260
|
+
|
261
|
+
+AC_ARG_ENABLE(valgrind,
|
262
|
+
+ [ --enable-valgrind use valgrind support],
|
263
|
+
+ [want_valgrind=$enableval], [want_valgrind=auto])
|
264
|
+
+
|
265
|
+
+if test x"$want_valgrind" != xno; then
|
266
|
+
+ AC_CHECK_HEADERS(valgrind/memcheck.h, have_valgrind=yes, have_valgrind=no)
|
267
|
+
+ if test x"$have_valgrind" = xyes; then
|
268
|
+
+ AC_DEFINE(HAVE_VALGRIND)
|
269
|
+
+ VALGRIND_CFLAGS="";
|
270
|
+
+ elif test x"$want_valgrind" = xyes -a x"$have_valgrind" = xno; then
|
271
|
+
+ AC_MSG_ERROR(valgrind support requested but valgrind not found)
|
272
|
+
+ else
|
273
|
+
+ VALGRIND_CFLAGS="";
|
274
|
+
+ fi
|
275
|
+
+fi
|
276
|
+
+
|
277
|
+
dnl default value for $KANJI
|
278
|
+
DEFAULT_KCODE="KCODE_NONE"
|
279
|
+
|
280
|
+
@@ -1565,6 +1581,7 @@
|
281
|
+
|
282
|
+
CPPFLAGS="$CPPFLAGS "'$(DEFS)'
|
283
|
+
AC_SUBST(XCFLAGS)dnl
|
284
|
+
+AC_SUBST(VALGRIND_CFLAGS)dnl
|
285
|
+
AC_SUBST(XLDFLAGS)dnl
|
286
|
+
AC_SUBST(LIBRUBY_LDSHARED)
|
287
|
+
AC_SUBST(LIBRUBY_DLDFLAGS)
|
288
|
+
diff -u eval.c eval.c
|
289
|
+
--- eval.c 2009-02-20 17:55:33.000000000 -0800
|
290
|
+
+++ eval.c 2009-02-20 18:06:52.000000000 -0800
|
291
|
+
@@ -28,6 +28,12 @@
|
292
|
+
#define EXIT_FAILURE 1
|
293
|
+
#endif
|
294
|
+
|
295
|
+
+#ifdef HAVE_VALGRIND
|
296
|
+
+#include <valgrind/memcheck.h>
|
297
|
+
+#else
|
298
|
+
+#define VALGRIND_MAKE_MEM_DEFINED(p, n) /* empty */
|
299
|
+
+#endif
|
300
|
+
+
|
301
|
+
#include <stdio.h>
|
302
|
+
|
303
|
+
#include "st.h"
|
304
|
+
@@ -5256,6 +5262,9 @@
|
305
|
+
int pcall;
|
306
|
+
{
|
307
|
+
ruby_current_node = lhs;
|
308
|
+
+
|
309
|
+
+ VALGRIND_MAKE_MEM_DEFINED(&val, sizeof(val));
|
310
|
+
+
|
311
|
+
if (val == Qundef) {
|
312
|
+
rb_warning("assigning void value");
|
313
|
+
val = Qnil;
|
314
|
+
diff -u gc.c gc.c
|
315
|
+
--- gc.c 2009-02-20 17:55:35.000000000 -0800
|
316
|
+
+++ gc.c 2009-02-20 18:10:38.000000000 -0800
|
317
|
+
@@ -30,6 +30,12 @@
|
318
|
+
#include <sys/resource.h>
|
319
|
+
#endif
|
320
|
+
|
321
|
+
+#ifdef HAVE_VALGRIND
|
322
|
+
+#include <valgrind/memcheck.h>
|
323
|
+
+#else
|
324
|
+
+#define VALGRIND_MAKE_MEM_DEFINED(p, n) /* empty */
|
325
|
+
+#endif
|
326
|
+
+
|
327
|
+
#if defined _WIN32 || defined __CYGWIN__
|
328
|
+
#include <windows.h>
|
329
|
+
#endif
|
330
|
+
@@ -99,6 +105,9 @@
|
331
|
+
{
|
332
|
+
void *mem;
|
333
|
+
|
334
|
+
+ VALGRIND_MAKE_MEM_DEFINED(&malloc_increase, sizeof(malloc_increase));
|
335
|
+
+ VALGRIND_MAKE_MEM_DEFINED(&malloc_limit, sizeof(malloc_limit));
|
336
|
+
+
|
337
|
+
if (size < 0) {
|
338
|
+
rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
|
339
|
+
}
|
340
|
+
@@ -257,8 +266,6 @@
|
341
|
+
}
|
342
|
+
}
|
343
|
+
|
344
|
+
-#undef GC_DEBUG
|
345
|
+
-
|
346
|
+
void
|
347
|
+
rb_global_variable(var)
|
348
|
+
VALUE *var;
|
349
|
+
@@ -293,10 +300,8 @@
|
350
|
+
struct RVarmap varmap;
|
351
|
+
struct SCOPE scope;
|
352
|
+
} as;
|
353
|
+
-#ifdef GC_DEBUG
|
354
|
+
char *file;
|
355
|
+
int line;
|
356
|
+
-#endif
|
357
|
+
} RVALUE;
|
358
|
+
|
359
|
+
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__)
|
360
|
+
@@ -315,6 +320,22 @@
|
361
|
+
static int heaps_length = 0;
|
362
|
+
static int heaps_used = 0;
|
363
|
+
|
364
|
+
+struct heaps_slot *
|
365
|
+
+rb_gc_heap_slots()
|
366
|
+
+{
|
367
|
+
+ return heaps;
|
368
|
+
+}
|
369
|
+
+
|
370
|
+
+int
|
371
|
+
+rb_gc_heaps_used() {
|
372
|
+
+ return heaps_used;
|
373
|
+
+}
|
374
|
+
+
|
375
|
+
+int
|
376
|
+
+rb_gc_heaps_length() {
|
377
|
+
+ return heaps_length;
|
378
|
+
+}
|
379
|
+
+
|
380
|
+
#define HEAP_MIN_SLOTS 10000
|
381
|
+
static int heap_slots = HEAP_MIN_SLOTS;
|
382
|
+
|
383
|
+
@@ -402,6 +423,11 @@
|
384
|
+
RANY(obj)->file = ruby_sourcefile;
|
385
|
+
RANY(obj)->line = ruby_sourceline;
|
386
|
+
#endif
|
387
|
+
+ if (ruby_current_node && ruby_current_node->nd_file) {
|
388
|
+
+ RANY(obj)->file = ruby_current_node->nd_file;
|
389
|
+
+ RANY(obj)->line = nd_line(ruby_current_node);
|
390
|
+
+ }
|
391
|
+
+
|
392
|
+
return obj;
|
393
|
+
}
|
394
|
+
|
395
|
+
@@ -638,6 +664,9 @@
|
396
|
+
register long n;
|
397
|
+
{
|
398
|
+
VALUE v;
|
399
|
+
+
|
400
|
+
+ VALGRIND_MAKE_MEM_DEFINED(x, sizeof(*x) * n);
|
401
|
+
+
|
402
|
+
while (n--) {
|
403
|
+
v = *x;
|
404
|
+
if (is_pointer_to_heap((void *)v)) {
|
405
|
+
@@ -728,11 +757,17 @@
|
406
|
+
{
|
407
|
+
register RVALUE *obj;
|
408
|
+
|
409
|
+
+ VALGRIND_MAKE_MEM_DEFINED(&ptr, sizeof(ptr));
|
410
|
+
obj = RANY(ptr);
|
411
|
+
+ VALGRIND_MAKE_MEM_DEFINED(obj, sizeof(*obj));
|
412
|
+
+
|
413
|
+
if (rb_special_const_p(ptr)) return; /* special const not marked */
|
414
|
+
if (obj->as.basic.flags == 0) return; /* free cell */
|
415
|
+
if (obj->as.basic.flags & FL_MARK) return; /* already marked */
|
416
|
+
+
|
417
|
+
obj->as.basic.flags |= FL_MARK;
|
418
|
+
+ /* mark our new reference point for sourcefile objects */
|
419
|
+
+ mark_source_filename(RANY(obj)->file);
|
420
|
+
|
421
|
+
if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) {
|
422
|
+
if (!mark_stack_overflow) {
|
423
|
+
diff -u parse.c parse.c
|
424
|
+
--- parse.c 2009-02-20 17:55:35.000000000 -0800
|
425
|
+
+++ parse.c 2009-02-20 18:07:07.000000000 -0800
|
426
|
+
@@ -11180,6 +11180,11 @@
|
427
|
+
* :wait2, :$>]
|
428
|
+
*/
|
429
|
+
|
430
|
+
+struct st_table *
|
431
|
+
+rb_parse_sym_tbl() {
|
432
|
+
+ return sym_tbl;
|
433
|
+
+}
|
434
|
+
+
|
435
|
+
VALUE
|
436
|
+
rb_sym_all_symbols()
|
437
|
+
{
|
438
|
+
diff -u parse.y parse.y
|
439
|
+
--- parse.y 2009-02-20 17:55:35.000000000 -0800
|
440
|
+
+++ parse.y 2009-02-20 18:07:07.000000000 -0800
|
441
|
+
@@ -6191,6 +6191,11 @@
|
442
|
+
* :wait2, :$>]
|
443
|
+
*/
|
444
|
+
|
445
|
+
+struct st_table *
|
446
|
+
+rb_parse_sym_tbl() {
|
447
|
+
+ return sym_tbl;
|
448
|
+
+}
|
449
|
+
+
|
450
|
+
VALUE
|
451
|
+
rb_sym_all_symbols()
|
452
|
+
{
|
453
|
+
diff -u version.h version.h
|
454
|
+
--- version.h 2009-02-20 17:55:36.000000000 -0800
|
455
|
+
+++ version.h 2009-02-20 18:07:51.000000000 -0800
|
456
|
+
@@ -2,7 +2,7 @@
|
457
|
+
#define RUBY_RELEASE_DATE "2008-08-08"
|
458
|
+
#define RUBY_VERSION_CODE 186
|
459
|
+
#define RUBY_RELEASE_CODE 20080808
|
460
|
+
-#define RUBY_PATCHLEVEL 286
|
461
|
+
+#define RUBY_PATCHLEVEL 903
|
462
|
+
|
463
|
+
#define RUBY_VERSION_MAJOR 1
|
464
|
+
#define RUBY_VERSION_MINOR 8
|
data/ruby/valgrind.patch
CHANGED
@@ -3,14 +3,14 @@ Index: Makefile.in
|
|
3
3
|
--- Makefile.in (revision 6439)
|
4
4
|
+++ Makefile.in (working copy)
|
5
5
|
@@ -34,7 +34,7 @@
|
6
|
-
|
6
|
+
|
7
7
|
empty =
|
8
8
|
OUTFLAG = @OUTFLAG@$(empty)
|
9
9
|
-CFLAGS = @CFLAGS@ @XCFLAGS@ @ARCH_FLAG@
|
10
10
|
+CFLAGS = @CFLAGS@ @XCFLAGS@ @ARCH_FLAG@ @VALGRIND_CFLAGS@
|
11
11
|
CPPFLAGS = -I. -I$(srcdir) @CPPFLAGS@
|
12
12
|
LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@
|
13
|
-
EXTLDFLAGS =
|
13
|
+
EXTLDFLAGS =
|
14
14
|
Index: configure.in
|
15
15
|
===================================================================
|
16
16
|
--- configure.in (revision 6439)
|
@@ -18,7 +18,7 @@ Index: configure.in
|
|
18
18
|
@@ -895,6 +895,22 @@
|
19
19
|
fi
|
20
20
|
fi
|
21
|
-
|
21
|
+
|
22
22
|
+AC_ARG_ENABLE(valgrind,
|
23
23
|
+ [ --enable-valgrind use valgrind support],
|
24
24
|
+ [want_valgrind=$enableval], [want_valgrind=auto])
|
@@ -37,10 +37,10 @@ Index: configure.in
|
|
37
37
|
+
|
38
38
|
dnl default value for $KANJI
|
39
39
|
DEFAULT_KCODE="KCODE_NONE"
|
40
|
-
|
40
|
+
|
41
41
|
@@ -1504,6 +1520,7 @@
|
42
42
|
esac
|
43
|
-
|
43
|
+
|
44
44
|
AC_SUBST(XCFLAGS)dnl
|
45
45
|
+AC_SUBST(VALGRIND_CFLAGS)dnl
|
46
46
|
AC_SUBST(XLDFLAGS)dnl
|
@@ -53,7 +53,7 @@ Index: eval.c
|
|
53
53
|
@@ -28,6 +28,12 @@
|
54
54
|
#define EXIT_FAILURE 1
|
55
55
|
#endif
|
56
|
-
|
56
|
+
|
57
57
|
+#ifdef HAVE_VALGRIND
|
58
58
|
+#include <valgrind/memcheck.h>
|
59
59
|
+#else
|
@@ -61,7 +61,7 @@ Index: eval.c
|
|
61
61
|
+#endif
|
62
62
|
+
|
63
63
|
#include <stdio.h>
|
64
|
-
|
64
|
+
|
65
65
|
#include "st.h"
|
66
66
|
@@ -5225,6 +5231,9 @@
|
67
67
|
int pcall;
|
@@ -80,7 +80,7 @@ Index: gc.c
|
|
80
80
|
@@ -30,6 +30,12 @@
|
81
81
|
#include <sys/resource.h>
|
82
82
|
#endif
|
83
|
-
|
83
|
+
|
84
84
|
+#ifdef HAVE_VALGRIND
|
85
85
|
+#include <valgrind/memcheck.h>
|
86
86
|
+#else
|
@@ -93,7 +93,7 @@ Index: gc.c
|
|
93
93
|
@@ -93,6 +99,9 @@
|
94
94
|
{
|
95
95
|
void *mem;
|
96
|
-
|
96
|
+
|
97
97
|
+ VALGRIND_MAKE_MEM_DEFINED(&malloc_increase, sizeof(malloc_increase));
|
98
98
|
+ VALGRIND_MAKE_MEM_DEFINED(&malloc_limit, sizeof(malloc_limit));
|
99
99
|
+
|
@@ -113,7 +113,7 @@ Index: gc.c
|
|
113
113
|
@@ -713,7 +725,10 @@
|
114
114
|
{
|
115
115
|
register RVALUE *obj;
|
116
|
-
|
116
|
+
|
117
117
|
+ VALGRIND_MAKE_MEM_DEFINED(&ptr, sizeof(ptr));
|
118
118
|
obj = RANY(ptr);
|
119
119
|
+ VALGRIND_MAKE_MEM_DEFINED(obj, sizeof(*obj));
|
data/test/benchmark/bench.rb
CHANGED
@@ -7,11 +7,11 @@ require 'rubygems'
|
|
7
7
|
require 'echoe'
|
8
8
|
require 'test/unit'
|
9
9
|
require 'bleak_house'
|
10
|
-
|
10
|
+
|
11
11
|
class BleakHouseTest < Test::Unit::TestCase
|
12
12
|
|
13
13
|
# Match the default hook filename, for convenience
|
14
|
-
FILE = "/tmp/bleak.#{Process.pid}.0.dump"
|
14
|
+
FILE = "/tmp/bleak.#{Process.pid}.0.dump"
|
15
15
|
|
16
16
|
def setup
|
17
17
|
File.delete FILE rescue nil
|
@@ -22,15 +22,15 @@ class BleakHouseTest < Test::Unit::TestCase
|
|
22
22
|
BleakHouse.snapshot(FILE)
|
23
23
|
assert File.exist?(FILE)
|
24
24
|
assert BleakHouse.heaps_used > 0
|
25
|
-
assert BleakHouse.heaps_length > 0
|
25
|
+
assert BleakHouse.heaps_length > 0
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def test_exception
|
29
29
|
assert_raises(RuntimeError) do
|
30
30
|
BleakHouse.snapshot("/")
|
31
|
-
end
|
31
|
+
end
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def test_analyze
|
35
35
|
BleakHouse.snapshot(FILE)
|
36
36
|
Dir.chdir(File.dirname(__FILE__) + "/../../bin") do
|
@@ -41,7 +41,7 @@ class BleakHouseTest < Test::Unit::TestCase
|
|
41
41
|
assert_match(/\d+ __null__:__null__:__node__/, output[4])
|
42
42
|
end
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
def test_signal
|
46
46
|
Echoe.silence do
|
47
47
|
system("kill -s SIGUSR2 #{Process.pid}")
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bleak_house
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: "4.2"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Weaver
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
yZ0=
|
31
31
|
-----END CERTIFICATE-----
|
32
32
|
|
33
|
-
date:
|
33
|
+
date: 2009-02-20 00:00:00 -08:00
|
34
34
|
default_executable:
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
@@ -73,17 +73,16 @@ files:
|
|
73
73
|
- LICENSE
|
74
74
|
- LICENSE_BSD
|
75
75
|
- Manifest
|
76
|
+
- Rakefile
|
76
77
|
- README
|
77
|
-
- ruby/
|
78
|
-
- ruby/
|
79
|
-
- ruby/ruby-1.8.6-p230.tar.bz2
|
78
|
+
- ruby/ruby-1.8.6-p286.tar.bz2
|
79
|
+
- ruby/ruby.patch
|
80
80
|
- ruby/valgrind.patch
|
81
81
|
- test/benchmark/bench.rb
|
82
82
|
- test/test_helper.rb
|
83
83
|
- test/unit/test_bleak_house.rb
|
84
84
|
- TODO
|
85
85
|
- bleak_house.gemspec
|
86
|
-
- Rakefile
|
87
86
|
has_rdoc: true
|
88
87
|
homepage: http://blog.evanweaver.com/files/doc/fauna/bleak_house/
|
89
88
|
post_install_message:
|
@@ -105,14 +104,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
104
|
version:
|
106
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
106
|
requirements:
|
108
|
-
- - "
|
107
|
+
- - ">="
|
109
108
|
- !ruby/object:Gem::Version
|
110
109
|
version: "1.2"
|
111
110
|
version:
|
112
111
|
requirements: []
|
113
112
|
|
114
113
|
rubyforge_project: fauna
|
115
|
-
rubygems_version: 1.
|
114
|
+
rubygems_version: 1.3.1
|
116
115
|
signing_key:
|
117
116
|
specification_version: 2
|
118
117
|
summary: A library for finding memory leaks.
|
metadata.gz.sig
CHANGED
Binary file
|
data/ruby/gc.patch
DELETED
@@ -1,129 +0,0 @@
|
|
1
|
-
Index: parse.y
|
2
|
-
===================================================================
|
3
|
-
--- parse.y (revision 6446)
|
4
|
-
+++ parse.y (working copy)
|
5
|
-
@@ -6168,6 +6168,11 @@
|
6
|
-
* :wait2, :$>]
|
7
|
-
*/
|
8
|
-
|
9
|
-
+struct st_table *
|
10
|
-
+rb_parse_sym_tbl() {
|
11
|
-
+ return sym_tbl;
|
12
|
-
+}
|
13
|
-
+
|
14
|
-
VALUE
|
15
|
-
rb_sym_all_symbols()
|
16
|
-
{
|
17
|
-
Index: parse.c
|
18
|
-
===================================================================
|
19
|
-
--- parse.c (revision 6446)
|
20
|
-
+++ parse.c (working copy)
|
21
|
-
@@ -11157,6 +11157,11 @@
|
22
|
-
* :wait2, :$>]
|
23
|
-
*/
|
24
|
-
|
25
|
-
+struct st_table *
|
26
|
-
+rb_parse_sym_tbl() {
|
27
|
-
+ return sym_tbl;
|
28
|
-
+}
|
29
|
-
+
|
30
|
-
VALUE
|
31
|
-
rb_sym_all_symbols()
|
32
|
-
{
|
33
|
-
Index: gc.c
|
34
|
-
===================================================================
|
35
|
-
--- gc.c (revision 6446)
|
36
|
-
+++ gc.c (working copy)
|
37
|
-
@@ -260,8 +260,6 @@
|
38
|
-
}
|
39
|
-
}
|
40
|
-
|
41
|
-
-#undef GC_DEBUG
|
42
|
-
-
|
43
|
-
void
|
44
|
-
rb_global_variable(var)
|
45
|
-
VALUE *var;
|
46
|
-
@@ -296,10 +294,8 @@
|
47
|
-
struct RVarmap varmap;
|
48
|
-
struct SCOPE scope;
|
49
|
-
} as;
|
50
|
-
-#ifdef GC_DEBUG
|
51
|
-
char *file;
|
52
|
-
int line;
|
53
|
-
-#endif
|
54
|
-
} RVALUE;
|
55
|
-
|
56
|
-
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__)
|
57
|
-
@@ -318,6 +314,22 @@
|
58
|
-
static int heaps_length = 0;
|
59
|
-
static int heaps_used = 0;
|
60
|
-
|
61
|
-
+struct heaps_slot *
|
62
|
-
+rb_gc_heap_slots()
|
63
|
-
+{
|
64
|
-
+ return heaps;
|
65
|
-
+}
|
66
|
-
+
|
67
|
-
+int
|
68
|
-
+rb_gc_heaps_used() {
|
69
|
-
+ return heaps_used;
|
70
|
-
+}
|
71
|
-
+
|
72
|
-
+int
|
73
|
-
+rb_gc_heaps_length() {
|
74
|
-
+ return heaps_length;
|
75
|
-
+}
|
76
|
-
+
|
77
|
-
#define HEAP_MIN_SLOTS 10000
|
78
|
-
static int heap_slots = HEAP_MIN_SLOTS;
|
79
|
-
|
80
|
-
@@ -386,16 +398,19 @@
|
81
|
-
rb_newobj()
|
82
|
-
{
|
83
|
-
VALUE obj;
|
84
|
-
-
|
85
|
-
+
|
86
|
-
if (!freelist) garbage_collect();
|
87
|
-
|
88
|
-
obj = (VALUE)freelist;
|
89
|
-
freelist = freelist->as.free.next;
|
90
|
-
- MEMZERO((void*)obj, RVALUE, 1);
|
91
|
-
-#ifdef GC_DEBUG
|
92
|
-
- RANY(obj)->file = ruby_sourcefile;
|
93
|
-
- RANY(obj)->line = ruby_sourceline;
|
94
|
-
-#endif
|
95
|
-
+
|
96
|
-
+ MEMZERO((void*)obj, RVALUE, 1);
|
97
|
-
+
|
98
|
-
+ if (ruby_current_node && ruby_current_node->nd_file) {
|
99
|
-
+ RANY(obj)->file = ruby_current_node->nd_file;
|
100
|
-
+ RANY(obj)->line = nd_line(ruby_current_node);
|
101
|
-
+ }
|
102
|
-
+
|
103
|
-
return obj;
|
104
|
-
}
|
105
|
-
|
106
|
-
@@ -732,7 +747,10 @@
|
107
|
-
if (rb_special_const_p(ptr)) return; /* special const not marked */
|
108
|
-
if (obj->as.basic.flags == 0) return; /* free cell */
|
109
|
-
if (obj->as.basic.flags & FL_MARK) return; /* already marked */
|
110
|
-
+
|
111
|
-
obj->as.basic.flags |= FL_MARK;
|
112
|
-
+ /* mark our new reference point for sourcefile objects */
|
113
|
-
+ mark_source_filename(RANY(obj)->file);
|
114
|
-
|
115
|
-
if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) {
|
116
|
-
if (!mark_stack_overflow) {
|
117
|
-
Index: version.h
|
118
|
-
===================================================================
|
119
|
-
--- version.h (revision 6439)
|
120
|
-
+++ version.h (working copy)
|
121
|
-
@@ -2,7 +2,7 @@
|
122
|
-
#define RUBY_RELEASE_DATE "2008-06-20"
|
123
|
-
#define RUBY_VERSION_CODE 186
|
124
|
-
#define RUBY_RELEASE_CODE 20080620
|
125
|
-
-#define RUBY_PATCHLEVEL 230
|
126
|
-
+#define RUBY_PATCHLEVEL 902
|
127
|
-
|
128
|
-
#define RUBY_VERSION_MAJOR 1
|
129
|
-
#define RUBY_VERSION_MINOR 8
|
Binary file
|