Bug #9247
closedBugs in socket.rb (exception retrieval)
Description
Ruby 2.1 (trunk) 2.0 and 1.9.3 both has a bug to retrieve exception.
In the following code, opened socket is always closed.
require 'socket'
ai = Addrinfo.tcp(nil, 12345)
begin
raise
rescue
p ai.listen #=> #Socket:(closed)
end
This is because in socket.rb, there are such error handling code:
creates a listening socket bound to self.¶
def listen(backlog=Socket::SOMAXCONN)
sock = Socket.new(self.pfamily, self.socktype, self.protocol)
begin
sock.ipv6only! if self.ipv6?
sock.setsockopt(:SOCKET, :REUSEADDR, 1)
sock.bind(self)
sock.listen(backlog)
if block_given?
yield sock
else
sock
end
ensure
### THIS LINE CLOSE `sock' every time when $! is not nil
sock.close if !sock.closed? && (block_given? || $!)
end
end
There are similar code in socket.rb.
akr-san already knows this issue.
This ticket is to note issues.
We realize this issue because webrick use this feature from 2.1.
The following code no longer works on 2.1.
begin
require 'xyzzy' # something like webrick
rescue LoadError
require 'webrick'
server = WEBrick::HTTPServer.new(Port: 12345)
end
Because $! is an instance of LoadError.
Updated by mrkn (Kenta Murata) over 10 years ago
- Description updated (diff)
I think the following code can reproduce the full cases:
https://gist.github.com/mrkn/7945798¶
require 'socket'
Addrinfo#connect_internal¶
puts "(1) Addrinfo#connect (connect_internal)"
begin
raise
rescue
p Addrinfo.tcp('www.ruby-lang.org', 80).connect
end
Addrinfo.bind¶
puts "\n(2) Addrinfo#bind"
begin
ai = Addrinfo.tcp(nil, 11229)
raise
rescue
begin
p ai.bind
end
end
Addrinfo.listen¶
puts "\n(3) Addrinfo#listen"
begin
ai = Addrinfo.tcp(nil, 11228)
raise
rescue
begin
p ai.listen
end
end
Socket.ip_sockets_port0¶
puts "\n(4) Socket.tcp_server_sockets (ip_sockets_port0)"
begin
raise
rescue
begin
Socket.tcp_server_sockets(0)
rescue IOError
$stderr.puts "#{$!.class}: #{$!}", $!.backtrace
end
end
Updated by mrkn (Kenta Murata) over 10 years ago
- Status changed from Open to Assigned
Updated by akr (Akira Tanaka) over 10 years ago
- Status changed from Assigned to Closed
- % Done changed from 0 to 100
This issue was solved with changeset r44184.
Koichi, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
-
ext/socket/lib/socket.rb: Don't test $! in "ensure" clause because
it may be set before the body.
Reported by ko1 and mrkn. [ruby-core:59088] [Bug #9247] -
lib/cgi/core.rb: Ditto.
-
lib/drb/ssl.rb: Ditto.
Updated by ko1 (Koichi Sasada) over 10 years ago
- Backport changed from 1.9.3: UNKNOWN, 2.0.0: UNKNOWN to 1.9.3: REQUIRED, 2.0.0: REQUIRED
Updated by ko1 (Koichi Sasada) over 10 years ago
- Status changed from Closed to Assigned
- Assignee changed from akr (Akira Tanaka) to nagachika (Tomoyuki Chikanaga)
Updated by nagachika (Tomoyuki Chikanaga) over 10 years ago
- Backport changed from 1.9.3: REQUIRED, 2.0.0: REQUIRED to 1.9.3: REQUIRED, 2.0.0: DONE
r44184 was backported to ruby_2_0_0 at r44390.
Updated by nagachika (Tomoyuki Chikanaga) over 10 years ago
- Assignee changed from nagachika (Tomoyuki Chikanaga) to usa (Usaku NAKAMURA)
Updated by hsbt (Hiroshi SHIBATA) about 10 years ago
- Target version changed from 2.1.0 to 2.2.0
Updated by usa (Usaku NAKAMURA) about 10 years ago
- Status changed from Assigned to Closed
- Target version deleted (
2.2.0) - Backport changed from 1.9.3: REQUIRED, 2.0.0: DONE to 1.9.3: DONE, 2.0.0: DONE
backported into ruby_1_9_3 at r44767.
BTW, this problem was fixed before releacing ruby 2.1, so all active branches are now OK.