ruby-trunk-changes r32369 - r32373

今日は数は少なめですが、Mac OS XLinux のスタックオーバフローの検出の修正がありました。スタックオーバフローを検出するためにどんなことをしているのかというのが垣間見えて興味深い修正でした。

kosaki:r32369 2011-07-03 04:59:05 +0900

スタックオーバフローの時に SystemStackError を発生させるための処理の Mac OS X での対応です。 Mac OS X ではスタックオーバフロー時に SIGSEGV ではなく SIGBUS が発生するので、sigbus でスタックオーバフローチェックを行うようにして、SIGBUS のシグナルハンドラも sigaltstack() で専用のスタック領域を利用するようにしています。またオーバフローの検出も Mac OS X ではスタックの最後に検出用の guard page という領域があってそこにスタックポインタが突入するとシグナルが飛ぶようになっているので、それを考慮してオーバフロー検出するようにしています。 pthread_attr_getguardsize() という API があってスタックの最後にどのくらいの guard page 領域が用意されているか取得できるんですね。 [ruby-core:24540] [Bug #1813]

svn:r32370 2011-07-03 04:59:14 +0900

version.h の日付更新。

kosaki:r32371 2011-07-03 06:18:16 +0900

こちらは Linux 用のスタックオーバフローチェックの不具合修正です。 スタックの底(というか天井というか、開始位置)のアドレスを計算するために pthread_attr_getstack() で取得した base address を使っていたけど、これにスタックサイズを加算しないといけなかった(スタックポインタはアドレスが減る方向に伸びていく)。また条件コンパイルの条件によって guard page のサイズがスタックサイズから2重に減算されていたのを修正しています。 [ruby-core:24540] [Bug #1813]
もの凄く根本的な不具合ですね。rb_thread_t::machine_stack_start は Fiber の FIBER_USE_NATIVE じゃない時にマシンスタックの退避のためにも利用されるのによく動いてたなとか思います。多分この条件にあてはまる環境で動かしてないのだと思いますが……。

nobu:r32373 2011-07-03 13:44:53 +0900

r32360 で Array#delete_if と Array#rejet! のブロックから途中で抜けた時の挙動を修正しましたが、抜けた後の yield していない要素が消えるようになっていたのを消えないように変更しています。 [Bug #2545]