Skip to content

Commit 3b62455

Browse files
committed
LeakChecker: skip CLOSE_WAIT sockets
Those FDs still live in the kernel space but have been closed in the user space.
1 parent 6ab9b22 commit 3b62455

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

tool/lib/leakchecker.rb

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def check_fd_leak(test_name)
7777
end
7878
(h[fd] ||= []) << [io, autoclose, inspect]
7979
}
80+
inspect = {}
8081
fd_leaked.select! {|fd|
8182
str = ''.dup
8283
pos = nil
@@ -98,6 +99,7 @@ def check_fd_leak(test_name)
9899
s = io.stat
99100
rescue Errno::EBADF
100101
# something un-stat-able
102+
live2.delete(fd)
101103
next
102104
else
103105
next if /darwin/ =~ RUBY_PLATFORM and [0, -1].include?(s.dev)
@@ -106,15 +108,35 @@ def check_fd_leak(test_name)
106108
io&.close
107109
end
108110
end
109-
puts "Leaked file descriptor: #{test_name}: #{fd}#{str}"
110-
puts " The IO was created at #{pos}" if pos
111+
inspect[fd] = [str, pos]
111112
true
112113
}
113114
unless fd_leaked.empty?
114115
unless @@try_lsof == false
115-
@@try_lsof |= system(*%W[lsof -w -a -d #{fd_leaked.minmax.uniq.join("-")} -p #$$], out: Test::Unit::Runner.output)
116+
open_list = IO.popen(%W[lsof -w -a -d #{fd_leaked.minmax.uniq.join("-")} -p #$$], &:readlines)
117+
if @@try_lsof |= $?.success?
118+
columns = (header = open_list.shift).split
119+
fd_index, node_index = columns.index('FD'), columns.index('NODE')
120+
open_list.reject! do |of|
121+
of = of.chomp.split(' ', node_index + 2)
122+
if of[node_index] == 'TCP' and of.last.end_with?('(CLOSE_WAIT)')
123+
fd = of[fd_index].to_i
124+
inspect.delete(fd)
125+
h.delete(fd)
126+
live2.delete(fd)
127+
true
128+
else
129+
false
130+
end
131+
end
132+
end
133+
puts(header, open_list) unless open_list.empty?
116134
end
117135
end
136+
inspect.each {|fd, (str, pos)|
137+
puts "Leaked file descriptor: #{test_name}: #{fd}#{str}"
138+
puts " The IO was created at #{pos}" if pos
139+
}
118140
h.each {|fd, list|
119141
next if list.length <= 1
120142
if 1 < list.count {|io, autoclose, inspect| autoclose }

0 commit comments

Comments
 (0)