bleak_house 4.1.1 → 4.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|