less is more

心のフルスタックエンジニア👨‍💻バイブスでコードを書いています🤘

ある日RubyがIllegal Instructionを吐いて死んでいたらそれはきっとsasscのせい

突然 Ruby が以下のエラーを吐いてお亡くなりになっていました。 より詳しくいうと、rakeタスクを実行した時に発生していて、rails cにも失敗します。なんかのgemが悪さしてる感がありますね 🤔

/usr/local/app/vendor/bundle/ruby/2.6.0/gems/ffi-1.11.1/lib/ffi/library.rb:112: [BUG] Illegal instruction at 0x00007f56aa5dadc5
ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]
-- Control frame information -----------------------------------------------
c:0080 p:---- s:0439 e:000438 CFUNC :open
c:0079 p:0022 s:0433 e:000432 BLOCK /usr/local/app/vendor/bundle/ruby/2.6.0/gems/ffi-1.11.1/lib/ffi/library.rb:112 [FINISH]
c:0078 p:---- s:0424 e:000423 CFUNC :each
c:0077 p:0113 s:0420 e:000419 BLOCK /usr/local/app/vendor/bundle/ruby/2.6.0/gems/ffi-1.11.1/lib/ffi/library.rb:109 [FINISH]
cz:0076 p:---- s:0413 e:000412 CFUNC :map
c:0075 p:0069 s:0409 e:000408 METHOD /usr/local/app/vendor/bundle/ruby/2.6.0/gems/ffi-1.11.1/lib/ffi/library.rb:99
c:0074 p:0079 s:0402 e:000401 CLASS /usr/local/app/vendor/bundle/ruby/2.6.0/gems/sassc-2.2.1/lib/sassc/native.rb:11
c:0073 p:0007 s:0398 e:000397 CLASS /usr/local/app/vendor/bundle/ruby/2.6.0/gems/sassc-2.2.1/lib/sassc/native.rb:6
c:0072 p:0014 s:0395 e:000394 TOP /usr/local/app/vendor/bundle/ruby/2.6.0/gems/sassc-2.2.1/lib/sassc/native.rb:5 [FINISH]
c:0071 p:---- s:0392 e:000391 CFUNC :require
c:0070 p:0013 s:0387 e:000386 BLOCK /usr/local/app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22
c:0069 p:0074 s:0384 e:000383 METHOD /usr/local/app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92
c:0068 p:0023 s:0372 e:000371 METHOD /usr/local/app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21
c:0067 p:0052 s:0366 e:000365 METHOD /usr/local/app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30
c:0066 p:0008 s:0359 e:000358 BLOCK /usr/local/app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies.rb:325
c:0065 p:0068 s:0356 e:000355 METHOD /usr/local/app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies.rb:291
c:0064 p:0011 s:0349 e:000348 METHOD /usr/local/app/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies.rb:325
c:0063 p:0037 s:0343 e:000342 METHOD /usr/local/app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:48
c:0062 p:0021 s:0337 e:000336 TOP /usr/local/app/vendor/bundle/ruby/2.6.0/gems/sassc-2.2.1/lib/sassc.rb:31 [FINISH]

まあ出オチなんですがsasscのせいでした。

解決方法

bundle installの前にこれをするだけでほぼ直ります。

bundle config --local build.sassc --disable-march-tune-native

もしくは、sasscを2.1.0以前にすることでも解決する模様。

原因

ものすごい数のコメントがついていて、9月からopenされてるissueですが、似たようなissueも他に報告されています。

github.com

これの経緯を要約します。

  • Jekyll という静的サイトジェネレータのv4.0.0がsasscの2.2.0に依存しているのだが、ビルドに失敗する。
  • v3.8.6に落としたらsasscが2.1.0になって解決する。
  • Alpine3.10 + Ruby2.6.3p62 + Rails5.2.3 on AWS ECS (FARGATE)CentOS7とRuby2.5といった環境でも同様の問題が再現するレポートがたくさんあげられる。
  • libsass.soの場所が違うからでは?という指摘。

    When installing the extension from 2.1.0, libsass.so is at ~/.gem/ruby/2.5.0/gems/sassc-2.1.0-x86_64-linux/lib/sassc/libsass.so. When building it from 2.2.0, it is at ~/.gem/ruby/2.5.0/gems/sassc-2.2.0/ext/libsass.so.

  • 2019/9/19 に 2.2.1のパッチバージョンがリリースされる
  • 同日に直ってませんというレポート😂
  • precompileの影響では?という指摘(たぶんこれが正しい)

で、前述の解決方法につながる。

つまりは、CPUアーキテクチャに最適化したビルドを行なった結果、ポータビリティがなくなって、異なるOS環境でうまく機能しないとうわけらしい。

--disable-march-tune-native で最適化を行わないようにすることができる。 デフォルトで最適化していなかったのだが、2.2.0から変更されたようだ。

自分は、CodeBuildでdocker18のプラットフォームでビルドされたイメージで今回の問題が起こった。どうりでmacでビルドして再現しないわけだ。

プラットフォーム起因の問題作る側も使う側の原因の特定も難しいよなあ...