From: Satoshi Shiba Date: 2011-08-27T22:20:40+09:00 Subject: [ruby-dev:44435] [BUG: ruby 1.9.3dev (2011-08-02 revision 32810) [i686-linux]] C の Proc の比較のバグ This is a multi-part message in MIME format. --------------040109020800030109010305 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit 芝と申します。 Proc#eq(C の関数は proc.c 内の proc_eq)で、C で定義した Proc (rb_proc_new などを用いて定義)の比較を行う箇所に不具合があります。 C で定義した Proc に対しても iseq を見て比較を行っているため、メモリの状 況如何で segv を吐いたり false のはずが true になったりします。 問題となる proc_eq は以下のようになっていて、Proc の種類にかかわらず、 proc->block.iseq->iseq_size, proc->block.iseq->local_size, proc->block.iseq->iseq を用いて比較しています。 proc->block.iseq が IFUNC_NODE だった場合は、関数ポインタの比較など、別 の方法で比較を行うべきです。 /* 問題の関数 */ static VALUE proc_eq(VALUE self, VALUE other) { if (self == other) { return Qtrue; } else { if (rb_obj_is_proc(other)) { rb_proc_t *p1, *p2; GetProcPtr(self, p1); GetProcPtr(other, p2); if (p1->envval == p2->envval && p1->block.iseq->iseq_size == p2->block.iseq->iseq_size && p1->block.iseq->local_size == p2->block.iseq->local_size && MEMCMP(p1->block.iseq->iseq, p2->block.iseq->iseq, VALUE, p1->block.iseq->iseq_size) == 0) { return Qtrue; } } } return Qfalse; } 添付する sample.zip に、proc_eq に対するパッチと問題となるコードの例をま とめて入れておきます。 今回のパッチでは、RUBY_VM_IFUNC_P で C の Proc かどうかを判定し、proc 2 つが共に C の Proc だった場合は、node->nd_cfnc, node->nd_aid, node->nd_tval で比較します。 参考にしていただければ幸いです。 よろしくお願いいたします。 /* パッチ */ diff --git proc.c proc.c index 427d1fe..e304295 100644 --- proc.c +++ proc.c @@ -766,7 +766,18 @@ proc_eq(VALUE self, VALUE other) rb_proc_t *p1, *p2; GetProcPtr(self, p1); GetProcPtr(other, p2); - if (p1->envval == p2->envval && + if (RUBY_VM_IFUNC_P(p1->block.iseq) && RUBY_VM_IFUNC_P(p2->block.iseq)) { + NODE *nd_ifunc1, *nd_ifunc2; + + nd_ifunc1 = (NODE *)p1->block.iseq; + nd_ifunc2 = (NODE *)p2->block.iseq; + if(nd_ifunc1->nd_cfnc == nd_ifunc2->nd_cfnc && + nd_ifunc1->nd_aid == nd_ifunc2->nd_aid && + rb_funcall(nd_ifunc1->nd_tval, idEq, 1, nd_ifunc2->nd_tval)) { + return Qtrue; + } + } else if (p1->envval == p2->envval && + !RUBY_VM_IFUNC_P(p1->block.iseq) && !RUBY_VM_IFUNC_P(p2->block.iseq) && p1->block.iseq->iseq_size == p2->block.iseq->iseq_size && p1->block.iseq->local_size == p2->block.iseq->local_size && MEMCMP(p1->block.iseq->iseq, p2->block.iseq->iseq, VALUE, --------------040109020800030109010305 Content-Type: application/x-zip-compressed; name="sample.zip" Content-Transfer-Encoding: base64 Content-Disposition: inline; filename="sample.zip" UEsDBBQAAAAAAHynGz9Hulb7KgAAACoAAAARAAAAc2FtcGxlL2V4dGNvbmYucmJyZXF1aXJl ICdta21mJwpjcmVhdGVfbWFrZWZpbGUoInNhbXBsZSIpCgpQSwMEFAAAAAgATa0bP7gZgE2A AQAArgMAABQAAABzYW1wbGUvcHJvY19lcS5wYXRjaI2TXU+DMBSGr+FXHG8WGJQMxE2zbJkf aExkTpMt8YowaLWRMAbdYjT777Z8OcZMxkV76Pu8PT09EFJCAKF3yiBJV4ERlJNM4xB/gW0N QpNgw8DnPdu6ugCz1+vbtowQqkBN06pwMgE06Pf1AWhiMi+BrwjNw2tlcf00dyDDEdGhiFfs A6eqDBLwJ116Ocmgm5g6H6xhqTxgNuPKjKVK4U5M9YiW78ZFi4soFykBJTHRGMfbrR/BaMTF +q3TkbWaep3fvHkL13u8n09vvVnuWkar4NOgGV6rHIYWYjUQFX74ftL0+c6Bbhx6lGziQNRR xbwcTRC1BiNQClxtphvuY9Y+ZrUwSpR6QzTmYUDiQFRa+/9W84pFyU2HT8O2QSzWPG+NUPwo OkjG+EXqQENnrQOvtbmFEKtryRuM2SaN4YWlG5yffVc2YAc4yvAJ3ZLOTuhTm7EOGf7tSE0n GovRy+g3rhIfF4+beehH/7r31MLuOu6te3j4Iot+NHf5w+jyL1BLAwQUAAAACAAsrhs/N1gX nc8AAABHAgAADwAAAHNhbXBsZS9zYW1wbGUuY72QPW/CMBCGd0v+D6ewBGRV4JWqEgMDEksH WC3bceBUc0aOE1RV/HdI+BBh6MfS8d6797l7b4BkfV04eI21+XzZvnHGWZV0Qgvr2XI1h0rv 9t4pLGuyk/yi6bgR13ajvQCk1Gr2Jo7ORXMrjA/24ywMOfviDCC6VEeCd0I/5ez47UL5jwv3 MdwDVs6XT/ZouglF7pD3fiI68vAntPw7Wj6hm4AFLAiTukzld45RhSuRnNr4YLRXrTthoDx7 DJeJXlYB4xb9W7vs2+XV3l12AlBLAwQUAAAACABnrhs/3lCFBG8AAAAuAQAAEAAAAHNhbXBs ZS9zYW1wbGUucmIrSi0szSxKVVAvTswtyEnVK85X5+IqMFCwVYAIxBcU5ScbamhyFRhiinEV lJYUK2iAlNsqFBhqKigrFGfkl+akKCSlKpQUlaYSZ5QRIaPSEnOKYWaBNFTXQsyAsYlzBVg1 WEABWT/EdAX8xkBdAABQSwECFAAUAAAAAAB8pxs/R7pW+yoAAAAqAAAAEQAAAAAAAAABACAA AAAAAAAAc2FtcGxlL2V4dGNvbmYucmJQSwECFAAUAAAACABNrRs/uBmATYABAACuAwAAFAAA AAAAAAABACAAAABZAAAAc2FtcGxlL3Byb2NfZXEucGF0Y2hQSwECFAAUAAAACAAsrhs/N1gX nc8AAABHAgAADwAAAAAAAAABACAAAAALAgAAc2FtcGxlL3NhbXBsZS5jUEsBAhQAFAAAAAgA Z64bP95QhQRvAAAALgEAABAAAAAAAAAAAQAgAAAABwMAAHNhbXBsZS9zYW1wbGUucmJQSwUG AAAAAAQABAD8AAAApAMAAAAA --------------040109020800030109010305--