こんにちは、なかむら(う)です。

In message "[ruby-list:42608] Debug Assertion Failed! on stable-snapshot"
    on Jul.29,2006 02:45:34, <tsyk / yk.rim.or.jp> wrote:
| リリースビルドでは問題なく実行が完了するのですが、
| 現在、ruby を LoadLibrary する DLL をデバッグしており、
| デバッグビルドした ruby を使いたいと思うのですが、
| この assertion failure を引き起こす原因は何でしょうか?

原因を説明、でいいんでしょうかね。

ext/socket/socket.cのinit_sock()の中で、同一のfdに対してfdopen()
が実行されているため、そこで生成されるfp->f、fp->f2の二つのフ
ァイルポインタは、実際には同じファイルディスクリプタを共有し
ます。
そして、このソケットのクローズはio.cのfptr_finalize()で行われ
るわけですが、まずfptr->f2がfclose()され、この時点でファイル
ディスクリプタもクローズされてしまいます。
そして、続いてfptr->fのflocse()が実行されるわけですが、内部で
既に閉じられているファイルディスクリプタを再び参照しようとし
ます。
普通のランタイムライブラリなら、単に「あー、もうクローズでき
ないや」ということでerrnoにEBADFをセットしてfclose()は失敗し
ます。で、Rubyのfptr_finalize()もそうなることを期待して書かれ
ています。
ところが、VC8のデバッグ版ランタイムは、ここで親切にファイルデ
ィスクリプタがクローズ済みかどうかチェックしてくれて、ありが
たいことにデバッグアサーションを表示してくれるわけです。

# 実際には、ランタイムのfclose()を呼ぶ前の、Windows版Ruby固有
# の姑息な処理のところで引っかかってるのですが、この姑息な処
# 理があってもなくてもやっぱりランタイムのfclose()の中で同じ
# デバッグアサーションに引っかかるはずなので、特にその辺は気
# にしなくてもよいでしょう、たぶん。


以上の情報があれば、win32/win32.cのrb_w32_fclose()なり、io.c
のfptr_finalize()なりにworkaroundを入れられるんじゃないかと思
いますので、がんばってください。


しかし、

| snapshot (1.9.0) でも同様のエラーになりました。

1.9では同一のファイルディスクリプタから複数のファイルポインタ
を生成する、なーんてことはしてないので、同じことは絶対に起き
ないはずなんですが、これも「呼び出し履歴」は取れますか?
取れるなら送っていただければ、来週辺りにチェックできると思い
ます。


それでは。
-- 
U.Nakamura <usa / garbagecollect.jp>