Ruby 2.7でのSEGVの件

結論

Ruby 2.7で以下のコードがSEGVする。

p **1


以下のコミットでmasterでは修正済み。

github.com

ただ、まだバックポートはされていない模様。

ちなみにバグ報告のチケットとしてはこちら

bugs.ruby-lang.org

Ruby 2.7でのSEGV

Ruby 2.7では以下のコードでSEGVが発生する。

p **1

原因としては **1 がキーワード引数として解釈されているため。

原因

**1 のケースだと 1 の部分がリテラルとして解釈されている。
そのため compile.cリテラルを処理している箇所でうまく処理がされず、SEGVが起きている模様(この辺の話はコミッタのmameさんからruby-jpで聞きました。誠にありがとうございます)

なので、以下のようにHashかどうかをチェックするようにすることでSEGVを回避しているみたい。

int empty_kw = nd_type(kw) == NODE_LIT && RB_TYPE_P(kw->nd_lit, T_HASH); 

RB_TYPE_P は第一引数に渡した値と第二引数に渡した値を比較して同じものかを判定している。
今回の場合でいくとHashかどうかをチェックしている感じ。

これによりHashではない値(今回の場合だと数値のリテラルとか)を渡した場合で例外が発生するようになった。

学び

compile.c がどういう処理で使われているかわからなかったんだけど、今回リテラルの処理とかに使われていると知れたのは良かった。
またデバッグしていく中でSEGVが起きている箇所と原因は判明してたけど、それ以外の個所で修正可能な内容だったので視野を広く持つべきだなあと思った。