bleak_house 3.4 → 3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/Manifest +0 -1
- data/README +1 -1
- data/ext/bleak_house/logger/build_ruby.rb +15 -8
- data/lib/bleak_house/analyzer/analyzer.rb +39 -11
- data.tar.gz.sig +0 -0
- metadata +2 -3
- metadata.gz.sig +0 -0
- data/LICENSE_RUBY +0 -53
data/CHANGELOG
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
|
2
|
+
v3.5. Explain when you need more frames. Use a cross-platform version of 'which'. Slight accuracy improvement.
|
3
|
+
|
2
4
|
v3.4. Clearer output descriptions; work around a Marshal bug on x64; fix for missing immortal leaks.
|
3
5
|
|
4
6
|
v3.3. Build Ruby in gem install step; bundle Ruby 1.8.6 source; fixes for truncated final frames.
|
data/Manifest
CHANGED
data/README
CHANGED
@@ -5,7 +5,7 @@ A library for finding memory leaks.
|
|
5
5
|
|
6
6
|
== License
|
7
7
|
|
8
|
-
Copyright 2007 Cloudburst, LLC. See the included LICENSE file. Portions copyright 2006 Eric Hodel and used with permission. See the included LICENSE_BSD file.
|
8
|
+
Copyright 2007 Cloudburst, LLC. See the included LICENSE file. Portions copyright 2006 Eric Hodel and used with permission. See the included LICENSE_BSD file.
|
9
9
|
|
10
10
|
The public certificate for this gem is at http://rubyforge.org/frs/download.php/25331/evan_weaver-original-public_cert.pem.
|
11
11
|
|
@@ -1,4 +1,6 @@
|
|
1
1
|
|
2
|
+
# Extension abuse in order to build our patched binary as part of the gem install process.
|
3
|
+
|
2
4
|
if RUBY_PLATFORM =~ /win32|windows/
|
3
5
|
raise "Windows is not supported."
|
4
6
|
end
|
@@ -8,7 +10,15 @@ tmp = "/tmp/"
|
|
8
10
|
|
9
11
|
require 'fileutils'
|
10
12
|
|
11
|
-
|
13
|
+
def which(basename)
|
14
|
+
# system('which') is not compatible across Linux and BSD
|
15
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).detect do |directory|
|
16
|
+
path = File.join(directory, basename.to_s)
|
17
|
+
path if File.exist? path
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
unless which('ruby-bleak-house')
|
12
22
|
|
13
23
|
Dir.chdir(tmp) do
|
14
24
|
build_dir = "bleak_house"
|
@@ -29,14 +39,10 @@ if `which ruby-bleak-house` =~ /no ruby-bleak-house in/
|
|
29
39
|
|
30
40
|
Dir.chdir("ruby-1.8.6") do
|
31
41
|
|
32
|
-
# Patch
|
42
|
+
# Patch, configure, and build
|
33
43
|
system("patch -p0 < \'#{source_dir}/gc.c.patch\' > ../gc.c.patch.log 2>&1")
|
34
44
|
system("patch -p0 < \'#{source_dir}/parse.y.patch\' > ../parse.y.patch.log 2>&1")
|
35
|
-
|
36
|
-
# Configure
|
37
45
|
system("./configure --prefix=#{binary_dir[0..-5]} > ../configure.log 2>&1") # --with-static-linked-ext
|
38
|
-
|
39
|
-
# Make
|
40
46
|
system("make > ../make.log 2>&1")
|
41
47
|
|
42
48
|
binary = "#{binary_dir}/ruby-bleak-house"
|
@@ -44,7 +50,8 @@ if `which ruby-bleak-house` =~ /no ruby-bleak-house in/
|
|
44
50
|
# Install binary
|
45
51
|
if File.exist? "ruby"
|
46
52
|
# Avoid "Text file busy" error
|
47
|
-
|
53
|
+
File.delete binary if File.exist? binary
|
54
|
+
exec("cp ./ruby #{binary}; chmod 755 #{binary}")
|
48
55
|
else
|
49
56
|
raise "Binary did not build"
|
50
57
|
end
|
@@ -58,4 +65,4 @@ if `which ruby-bleak-house` =~ /no ruby-bleak-house in/
|
|
58
65
|
# Success
|
59
66
|
end
|
60
67
|
|
61
|
-
end
|
68
|
+
end
|
@@ -23,6 +23,15 @@ module BleakHouse
|
|
23
23
|
open(
|
24
24
|
File.dirname(__FILE__) + '/../../../ext/bleak_house/logger/snapshot.h'
|
25
25
|
).read[/\{(.*?)\}/m, 1] + ']')
|
26
|
+
|
27
|
+
def self.backwards_detect(array)
|
28
|
+
i = array.size - 1
|
29
|
+
while i >= 0
|
30
|
+
item = array[i]
|
31
|
+
return item if yield(item)
|
32
|
+
i -= 1
|
33
|
+
end
|
34
|
+
end
|
26
35
|
|
27
36
|
def self.calculate!(frame, index, total, obj_count = nil)
|
28
37
|
bsize = frame['births'].size
|
@@ -70,8 +79,13 @@ module BleakHouse
|
|
70
79
|
else
|
71
80
|
# Rebuild frames
|
72
81
|
total_frames = `grep '^-1' #{logfile} | wc`.to_i - 2
|
73
|
-
|
82
|
+
|
74
83
|
puts "#{total_frames} frames"
|
84
|
+
|
85
|
+
if total_frames < INITIAL_SKIP * 3
|
86
|
+
puts "Not enough frames for accurate results. Please record at least #{INITIAL_SKIP * 3} frames."
|
87
|
+
exit!
|
88
|
+
end
|
75
89
|
|
76
90
|
Ccsv.foreach(logfile) do |row|
|
77
91
|
|
@@ -121,7 +135,7 @@ module BleakHouse
|
|
121
135
|
end
|
122
136
|
|
123
137
|
frames = frames[0..-2]
|
124
|
-
frames.last['objects'] = frames.last['objects'].to_a # Work around a Marshal bug
|
138
|
+
frames.last['objects'] = frames.last['objects'].to_a # Work around a Marshal bug x86-64
|
125
139
|
|
126
140
|
# Cache the result
|
127
141
|
File.open(cachefile, 'w') do |f|
|
@@ -130,14 +144,24 @@ module BleakHouse
|
|
130
144
|
|
131
145
|
end
|
132
146
|
|
147
|
+
puts "\nRehashing."
|
148
|
+
|
133
149
|
# Convert births back to hashes, necessary due to the Marshal workaround
|
134
150
|
frames.each do |frame|
|
135
|
-
frame['
|
151
|
+
frame['births_hash'] = {}
|
152
|
+
frame['births'].each do |key, value|
|
153
|
+
frame['births_hash'][key] = value
|
154
|
+
end
|
155
|
+
frame.delete('births')
|
136
156
|
end
|
157
|
+
|
158
|
+
# require 'ruby-debug'; Debugger.start
|
159
|
+
#
|
160
|
+
# debugger
|
137
161
|
|
138
162
|
# See what objects are still laying around
|
139
163
|
population = frames.last['objects'].reject do |key, value|
|
140
|
-
frames.first['
|
164
|
+
frames.first['births_hash'][key] == value
|
141
165
|
end
|
142
166
|
|
143
167
|
puts "\n#{frames.size - 1} full frames. Removing #{INITIAL_SKIP} frames from each end of the run to account for\nstartup overhead and GC lag."
|
@@ -146,7 +170,7 @@ module BleakHouse
|
|
146
170
|
frames = frames[INITIAL_SKIP..-INITIAL_SKIP]
|
147
171
|
|
148
172
|
total_births = frames.inject(0) do |births, frame|
|
149
|
-
births + frame['
|
173
|
+
births + frame['births_hash'].size
|
150
174
|
end
|
151
175
|
total_deaths = frames.inject(0) do |deaths, frame|
|
152
176
|
deaths + frame['deaths'].size
|
@@ -155,13 +179,16 @@ module BleakHouse
|
|
155
179
|
puts "\n#{total_births} total births, #{total_deaths} total deaths, #{population.size} uncollected objects."
|
156
180
|
|
157
181
|
leakers = {}
|
158
|
-
|
182
|
+
|
183
|
+
# debugger
|
184
|
+
|
159
185
|
# Find the sources of the leftover objects in the final population
|
160
186
|
population.each do |id, klass|
|
161
|
-
leaker = frames
|
162
|
-
frame['
|
187
|
+
leaker = backwards_detect(frames) do |frame|
|
188
|
+
frame['births_hash'][id] == klass
|
163
189
|
end
|
164
190
|
if leaker
|
191
|
+
# debugger
|
165
192
|
tag = leaker['meta']['tag']
|
166
193
|
klass = CLASS_KEYS[klass] if klass.is_a? Fixnum
|
167
194
|
leakers[tag] ||= Hash.new(0)
|
@@ -211,9 +238,10 @@ module BleakHouse
|
|
211
238
|
impacts.each do |tag, total|
|
212
239
|
puts " #{format('%.4f', total).rjust(7)}: #{tag}"
|
213
240
|
end
|
214
|
-
|
215
|
-
|
216
|
-
|
241
|
+
|
242
|
+
puts "\nDone"
|
243
|
+
|
244
|
+
end
|
217
245
|
|
218
246
|
end
|
219
247
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4.6
|
|
3
3
|
specification_version: 2
|
4
4
|
name: bleak_house
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: "3.
|
7
|
-
date: 2007-
|
6
|
+
version: "3.5"
|
7
|
+
date: 2007-11-14 00:00:00 -05:00
|
8
8
|
summary: A library for finding memory leaks.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -80,7 +80,6 @@ files:
|
|
80
80
|
- lib/bleak_house.rb
|
81
81
|
- LICENSE
|
82
82
|
- LICENSE_BSD
|
83
|
-
- LICENSE_RUBY
|
84
83
|
- Manifest
|
85
84
|
- Rakefile
|
86
85
|
- README
|
metadata.gz.sig
CHANGED
Binary file
|
data/LICENSE_RUBY
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
$BK\%W%m%0%i%`$O%U%j!<%=%U%H%&%'%"$G$9!%(BGPL(the GNU General
|
2
|
-
Public License)$B$^$?$O0J2<$K<($9>r7o$GK\%W%m%0%i%`$r:FG[I[$G(B
|
3
|
-
$B$-$^$9!%(BGPL$B$K$D$$$F$O(BCOPYING.txt$B%U%!%$%k$r;2>H$7$F2<$5$$!%(B
|
4
|
-
|
5
|
-
1. $BJ#@=$O@)8B$J$/<+M3$G$9!%(B
|
6
|
-
|
7
|
-
2. $B0J2<$N>r7o$N$$$:$l$+$rK~$?$9;~$KK\%W%m%0%i%`$N%=!<%9$r(B
|
8
|
-
$B<+M3$KJQ99$G$-$^$9!%(B
|
9
|
-
|
10
|
-
(a) $B%M%C%H%K%e!<%:$K%]%9%H$7$?$j!$:n<T$KJQ99$rAwIU$9$k(B
|
11
|
-
$B$J$I$NJ}K!$G!$JQ99$r8x3+$9$k!%(B
|
12
|
-
|
13
|
-
(b) $BJQ99$7$?K\%W%m%0%i%`$r<+J,$N=jB0$9$kAH?%FbIt$@$1$G(B
|
14
|
-
$B;H$&!%(B
|
15
|
-
|
16
|
-
(c) $BJQ99E@$rL@<($7$?$&$(!$%=%U%H%&%'%"$NL>A0$rJQ99$9$k!%(B
|
17
|
-
$B$=$N%=%U%H%&%'%"$rG[I[$9$k;~$K$OJQ99A0$NK\%W%m%0%i(B
|
18
|
-
$B%`$bF1;~$KG[I[$9$k!%$^$?$OJQ99A0$NK\%W%m%0%i%`$N%=!<(B
|
19
|
-
$B%9$NF~<jK!$rL@<($9$k!%(B
|
20
|
-
|
21
|
-
(d) $B$=$NB>$NJQ99>r7o$r:n<T$H9g0U$9$k!%(B
|
22
|
-
|
23
|
-
3. $B0J2<$N>r7o$N$$$:$l$+$rK~$?$9;~$KK\%W%m%0%i%`$r%3%s%Q%$(B
|
24
|
-
$B%k$7$?%*%V%8%'%/%H%3!<%I$d<B9T7A<0$G$bG[I[$G$-$^$9!%(B
|
25
|
-
|
26
|
-
(a) $B%P%$%J%j$r<u$1<h$C$??M$,%=!<%9$rF~<j$G$-$k$h$&$K!$(B
|
27
|
-
$B%=!<%9$NF~<jK!$rL@<($9$k!%(B
|
28
|
-
|
29
|
-
(b) $B5!3#2DFI$J%=!<%9%3!<%I$rE:IU$9$k!%(B
|
30
|
-
|
31
|
-
(c) $BJQ99$r9T$C$?%P%$%J%j$OL>A0$rJQ99$7$?$&$(!$%*%j%8%J(B
|
32
|
-
$B%k$N%=!<%9%3!<%I$NF~<jK!$rL@<($9$k!%(B
|
33
|
-
|
34
|
-
(d) $B$=$NB>$NG[I[>r7o$r:n<T$H9g0U$9$k!%(B
|
35
|
-
|
36
|
-
4. $BB>$N%W%m%0%i%`$X$N0zMQ$O$$$+$J$kL\E*$G$"$l<+M3$G$9!%$?(B
|
37
|
-
$B$@$7!$K\%W%m%0%i%`$K4^$^$l$kB>$N:n<T$K$h$k%3!<%I$O!$$=(B
|
38
|
-
$B$l$>$l$N:n<T$N0U8~$K$h$k@)8B$,2C$($i$k>l9g$,$"$j$^$9!%(B
|
39
|
-
|
40
|
-
$B6qBNE*$K$O(Bgc.c($B0lIt(B)$B!$(Butil.c($B0lIt(B)$B!$(Bst.[ch]$B!$(Bregex.[ch]
|
41
|
-
$B$*$h$S(B ./missing$B%G%#%l%/%H%j2<$N%U%!%$%k72$,3:Ev$7$^$9!%(B
|
42
|
-
$B$=$l$>$l$NG[I[>r7o$J$I$KIU$$$F$O3F%U%!%$%k$r;2>H$7$F$/(B
|
43
|
-
$B$@$5$$!%(B
|
44
|
-
|
45
|
-
5. $BK\%W%m%0%i%`$X$NF~NO$H$J$k%9%/%j%W%H$*$h$S!$K\%W%m%0%i(B
|
46
|
-
$B%`$+$i$N=PNO$N8"Mx$OK\%W%m%0%i%`$N:n<T$G$O$J$/!$$=$l$>(B
|
47
|
-
$B$l$NF~=PNO$r@8@.$7$??M$KB0$7$^$9!%$^$?!$K\%W%m%0%i%`$K(B
|
48
|
-
$BAH$_9~$^$l$k$?$a$N3HD%%i%$%V%i%j$K$D$$$F$bF1MM$G$9!%(B
|
49
|
-
|
50
|
-
6. $BK\%W%m%0%i%`$OL5J]>Z$G$9!%:n<T$OK\%W%m%0%i%`$r%5%]!<%H(B
|
51
|
-
$B$9$k0U;V$O$"$j$^$9$,!$%W%m%0%i%`<+?H$N%P%0$"$k$$$OK\%W(B
|
52
|
-
$B%m%0%i%`$N<B9T$J$I$+$iH/@8$9$k$$$+$J$kB;32$KBP$7$F$b@U(B
|
53
|
-
$BG$$r;}$A$^$;$s!%(B
|