summaryrefslogtreecommitdiff
path: root/tool/lib/leakchecker.rb
diff options
context:
space:
mode:
Diffstat (limited to 'tool/lib/leakchecker.rb')
-rw-r--r--tool/lib/leakchecker.rb36
1 files changed, 32 insertions, 4 deletions
diff --git a/tool/lib/leakchecker.rb b/tool/lib/leakchecker.rb
index 69aeb2c254..33a546699f 100644
--- a/tool/lib/leakchecker.rb
+++ b/tool/lib/leakchecker.rb
@@ -77,6 +77,7 @@ class LeakChecker
end
(h[fd] ||= []) << [io, autoclose, inspect]
}
+ inspect = {}
fd_leaked.select! {|fd|
str = ''.dup
pos = nil
@@ -98,6 +99,7 @@ class LeakChecker
s = io.stat
rescue Errno::EBADF
# something un-stat-able
+ live2.delete(fd)
next
else
next if /darwin/ =~ RUBY_PLATFORM and [0, -1].include?(s.dev)
@@ -106,15 +108,41 @@ class LeakChecker
io&.close
end
end
- puts "Leaked file descriptor: #{test_name}: #{fd}#{str}"
- puts " The IO was created at #{pos}" if pos
+ inspect[fd] = [str, pos]
true
}
unless fd_leaked.empty?
unless @@try_lsof == false
- @@try_lsof |= system(*%W[lsof -a -d #{fd_leaked.minmax.uniq.join("-")} -p #$$], out: Test::Unit::Runner.output)
+ begin
+ open_list = IO.popen(%W[lsof -w -a -d #{fd_leaked.minmax.uniq.join("-")} -p #$$], &:readlines)
+ rescue
+ @@try_lsof = false
+ else
+ @@try_lsof |= $?.success?
+ end
+ if header = open_list&.shift
+ columns = header.split
+ fd_index, node_index = columns.index('FD'), columns.index('NODE')
+ open_list.reject! do |of|
+ of = of.chomp.split(' ', node_index + 2)
+ if of[node_index] == 'TCP' and of.last.end_with?('(CLOSE_WAIT)')
+ fd = of[fd_index].to_i
+ inspect.delete(fd)
+ h.delete(fd)
+ live2.delete(fd)
+ true
+ else
+ false
+ end
+ end
+ puts(header, open_list) unless open_list.empty?
+ end
end
end
+ inspect.each {|fd, (str, pos)|
+ puts "Leaked file descriptor: #{test_name}: #{fd}#{str}"
+ puts " The IO was created at #{pos}" if pos
+ }
h.each {|fd, list|
next if list.length <= 1
if 1 < list.count {|io, autoclose, inspect| autoclose }
@@ -156,7 +184,7 @@ class LeakChecker
[prev_count, []]
else
tempfiles = ObjectSpace.each_object(Tempfile).reject {|t|
- t.instance_variables.empty? || t.closed?
+ t.instance_variables.empty? || (t.closed? rescue true)
}
[count, tempfiles]
end