[Ruby 1.9-Bug#4387][Open] test socket connect nonblock(TestSocketAddrinfo) がまれに失敗する

Bug #4387: test_socket_connect_nonblock(TestSocketAddrinfo) がまれに失敗する
http://redmine.ruby-lang.org/issues/show/4387

起票者: Motohiro KOSAKI
ステータス: Open, 優先度: Normal
カテゴリ: core, Target version: 1.9.x
ruby -v: ruby 1.9.3dev (2011-02-09 trunk 30831) [i386-mswin32_100]

1割ぐらいの確率でtest-allが以下のエラーを吐きます

  1. Error:
    test_socket_connect_nonblock(TestSocketAddrinfo):
    Errno::EINVAL: Invalid argument - connect(2)
    C:/ruby/trunk/test/socket/test_addrinfo.rb:163:in connect_nonblock' C:/ruby/trunk/test/socket/test_addrinfo.rb:163:in rescue in
    test_socket_con
    nect_nonblock’
    C:/ruby/trunk/test/socket/test_addrinfo.rb:158:in
    `test_socket_connect_nonbl
    ock’

なお、OSレベルでは WSAGetLastError() が WSAEINVALを返しています。

MSDNからそれっぽい部分をいくつかピックアップすると

WSAEALREADY: A nonblocking connect call is in progress on the specified
socket.
Note In order to preserve backward compatibility, this
error is reported as
WSAEINVAL to Windows Sockets 1.1 applications that link to
either Winsock.dll or
Wsock32.dll.
WSAEINVAL: The parameter s is a listening socket.

とあるので、
o selectが正しく動いておらず、connect完了する前に処理がもどってしまうので、connectがEINVALを返している
o selectはちゃんと動いているけど、connectがトチ狂ってEISCONNを返さずにEINVALを返している

の2択なんですが、どちらなのかは切り分けできませんでした。誰か良い案があれば教えてください。

これだけではアレなので、いくつか調査報告など

w3cのhttpのサンプルコードだと、EINVALはEISCONNと同等の処理をするようになっています。
http://www.w3.org/Library/src/HTTCP.c

NetBSDのconnectにも昔EINVALを返す問題があったそうですが、どう対処したのかはよく分かりませんでした
http://mail-index.netbsd.org/netbsd-bugs/2003/08/18/0002.html
↑ なんと報告者は Kambeさん

ruby-talkでそれっぽい話をしているログをみつけたのですが、こちらも結論分からず。
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/16632

チケット #4387 が更新されました。 (by Motohiro KOSAKI)

不思議なことに以下の2つはほぼ同等の処理をしているにも関わらず、test_connect_nonblockは失敗しません

test_nonblock.rb: test_connect_nonblock()
test_addrinfo.rb: test_socket_connect_nonblock()

チケット #4387 が更新されました。 (by Motohiro KOSAKI)

WSAConnect()はWSAEALREADYを返すべきタイミングでWSAEINVALを返すことはなさそうだったので、単純にconnectをWSAConnect()に置換してみたのですが、やっぱりWSAEINVALが帰ってきますねぇ。おてあげ

チケット #4387 が更新されました。 (by Usaku NAKAMURA)

これも見たことないですねえ。1割も確率があるなら私も踏んでよさそうなんですが。
Winsockの(あるいはOSの)バージョンによってはなんかタイミングバグがあるとかかしら。

ところで、ふと思ったんですけど、ウィルス対策ソフトとか何か入ってますか?

チケット #4387 が更新されました。 (by Usaku NAKAMURA)

これも見たことないですねえ。1割も確率があるなら私も踏んでよさそうなんですが。
Winsockの(あるいはOSの)バージョンによってはなんかタイミングバグがあるとかかしら。

ところで、ふと思ったんですけど、ウィルス対策ソフトとか何か入ってますか?

OSはVista 32bitでMicrosoft Security Essential が入っています。
実は Security Essential は個人的にちょっと疑っています。 :wink:

チケット #4387 が更新されました。 (by Motohiro KOSAKI)

Security
Essentialをいったん外して実験してみました。再現率が有為に下がったのですが、まだ100回に一回ぐらい同様の現象が起きます。
確率が変わるのはSecurity
Essentialが挙動を変えてるんじゃなく、localhostでのテストだからタイミングがちょっと変わっただけで挙動が変わってしまうというオチではないかと予想しています。
うーむ、Vistaが腐っていると思うべきなのだろうか。