Ruby アプリのセグメンテーション違反の修正
最終更新日 2022年03月09日(水)
Table of Contents
ソフトウェアを実行しているコンピュータに対して無効なメモリコマンドをソフトウェアから発行しようとすると、セグメンテーション違反が発生することがあります。アプリケーションでセグメンテーション違反が発生している場合は、次のように、非常に冗長なエラーが出力されます。
2016-05-10T03:04:11.572681+00:00 app[web.1]: -- Control frame information -----------------------------------------------
2016-05-10T03:04:11.582158+00:00 app[web.1]: 975 /app/vendor/bundle/ruby/2.2.0/gems/sass-3.4.22/lib/sass/supports.rb
2016-05-10T03:04:11.572682+00:00 app[web.1]: c:0001 p:---- s:0002 e:000001 TOP [FINISH]
2016-05-10T03:04:11.582159+00:00 app[web.1]: 976 /app/vendor/bundle/ruby/2.2.0/gems/sass-3.4.22/lib/sass/engine.rb
2016-05-10T03:04:11.582160+00:00 app[web.1]: 977 /app/vendor/bundle/ruby/2.2.0/gems/sass-3.4.22/lib/sass/railtie.rb
2016-05-10T03:04:11.572683+00:00 app[web.1]:
2016-05-10T03:04:11.582162+00:00 app[web.1]: 978 /app/vendor/bundle/ruby/2.2.0/gems/sass-3.4.22/lib/sass/features.rb
2016-05-10T03:04:11.582162+00:00 app[web.1]: 979 /app/vendor/bundle/ruby/2.2.0/gems/sass-3.4.22/lib/sass.rb
2016-05-10T03:04:11.572684+00:00 app[web.1]:
2016-05-10T03:04:11.582163+00:00 app[web.1]: 980 /app/vendor/bundle/ruby/2.2.0/gems/sprockets-3.6.0/lib/sprockets/sass_functions.rb
2016-05-10T03:04:11.572684+00:00 app[web.1]: -- C level backtrace information -------------------------------------------
2016-05-10T03:04:11.580053+00:00 app[web.1]: /app/vendor/ruby-2.2.2/bin/ruby(rb_vm_bugreport+0x51f) [0x7fc9c783dfbf] vm_dump.c:693
2016-05-10T03:04:11.580095+00:00 app[web.1]: /app/vendor/ruby-2.2.2/bin/ruby(rb_bug+0xca) [0x7fc9c78af95a] error.c:409
2016-05-10T03:04:11.580156+00:00 app[web.1]: /app/vendor/ruby-2.2.2/bin/ruby(newobj_of+0x1be) [0x7fc9c770932e] gc.c:1635
2016-05-10T03:04:11.580241+00:00 app[web.1]: /app/vendor/ruby-2.2.2/bin/ruby(rb_str_dup+0x1b) [0x7fc9c77c3fcb] string.c:552
2016-05-10T03:04:11.582165+00:00 app[web.1]: 981 /app/vendor/bundle/ruby/2.2.0/gems/sass-rails-5.0.4/lib/sass/rails/helpers.rb
2016-05-10T03:04:11.580402+00:00 app[web.1]: /app/vendor/ruby-2.2.2/bin/ruby(rb_class_path+0x83) [0x7fc9c77fea03] variable.c:259
2016-05-10T03:04:11.580460+00:00 app[web.1]: /app/vendor/ruby-2.2.2/bin/ruby(thread_start_func_2+0x1e1) [0x7fc9c784c5c1] thread.c:2717
2016-05-10T03:04:11.580543+00:00 app[web.1]: /app/vendor/ruby-2.2.2/bin/ruby(thread_start_func_1+0xbb) [0x7fc9c784d0eb] thread_pthread.c:846
2016-05-10T03:04:11.580604+00:00 app[web.1]: /lib/x86_64-linux-gnu/libpthread.so.0(start_thread+0xc2) [0x7fc9c7285182]
2016-05-10T03:04:11.580654+00:00 app[web.1]: /lib/x86_64-linux-gnu/libc.so.6(__clone+0x6d) [0x7fc9c686f47d]
2016-05-10T03:04:11.580656+00:00 app[web.1]:
C で記述された MRI Ruby VM (YARV) でセグメンテーション違反が発生する可能性がありますが、これは非常にまれです。Ruby 2 以降に対応した VM は高い安定性を保っており、純粋な Ruby コードを記述してセグメンテーション違反が発生することはまれです。セグメンテーション違反の原因は通常、C 拡張機能です。
C 拡張機能は、Ruby によってコンパイルされ、Ruby がインターフェースとなる C コードを持つ Rubygem です。C 拡張機能を使用または記述する理由はさまざまです。 コードの中で特にパフォーマンスが重視される部分を C で記述して速度の向上を図ることができます。ヘッダーのインポートや API の直接使用によって Heroku 上のライブラリを直接利用するために C 拡張機能を使用することもできます。
アプリケーションでセグメンテーション違反が発生している場合、使用しているライブラリのどれに C 拡張機能が含まれているかを特定する必要があります。この情報は IRB で次のコマンドを実行して確認できます。
$ bundle show --paths | ruby -e "STDIN.each_line {|dep| puts dep.split('/').last if File.directory?(File.join(dep.chomp, 'ext')) }"
bcrypt-3.1.11
bluecloth-2.2.0
debug_inspector-0.0.2
ffi-1.9.10
nio4r-1.2.1
nokogiri-1.6.7.2
pg-0.18.3
puma-3.0.0.rc1
rb-fsevent-0.9.7
rusage-0.2.0
scout_apm-2.0.0.pre
thread_safe-0.3.5
websocket-driver-0.6.3
unf_ext-0.0.7.2
このリストは、オープンソースアプリケーションの CodeTriage から生成されたものです。
セグメンテーション違反の修正
C 拡張機能のリストを取得したら、拡張機能のアップグレード、または最新のリリースバージョンの Ruby が入手可能かどうか調査します。Ruby サポートページでリストを確認できます。最新の利用可能なバージョンを実行することを常に推奨しています。
C 拡張機能および Ruby のバージョンをアップグレードしても解決しない場合、セグメンテーション違反の Ruby バックトレースを使用して詳細を確認できます。省略した例を次に示します。
2016-05-10T03:04:11.580659+00:00 app[web.1]: -- Other runtime information -----------------------------------------------
2016-05-10T03:04:11.580659+00:00 app[web.1]:
2016-05-10T03:04:11.580661+00:00 app[web.1]: * Loaded script: puma: cluster worker 1: 27 [app]
2016-05-10T03:04:11.580662+00:00 app[web.1]:
2016-05-10T03:04:11.580663+00:00 app[web.1]: * Loaded features:
2016-05-10T03:04:11.580664+00:00 app[web.1]:
2016-05-10T03:04:11.580667+00:00 app[web.1]: 0 enumerator.so
2016-05-10T03:04:11.580668+00:00 app[web.1]: 1 rational.so
2016-05-10T03:04:11.580668+00:00 app[web.1]: 2 complex.so
2016-05-10T03:04:11.580671+00:00 app[web.1]: 3 /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/x86_64-linux/enc/encdb.so
2016-05-10T03:04:11.580671+00:00 app[web.1]: 4 /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/x86_64-linux/enc/trans/transdb.so
2016-05-10T03:04:11.580672+00:00 app[web.1]: 5 /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/unicode_normalize.rb
2016-05-10T03:04:11.580673+00:00 app[web.1]: 6 /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/x86_64-linux/rbconfig.rb
2016-05-10T03:04:11.580675+00:00 app[web.1]: 7 thread.rb
2016-05-10T03:04:11.580676+00:00 app[web.1]: 8 /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/x86_64-linux/thread.so
2016-05-10T03:04:11.580676+00:00 app[web.1]: 9 /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rubygems/compatibility.rb
2016-05-10T03:04:11.580677+00:00 app[web.1]: 10 /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rubygems/defaults.rb
2016-05-10T03:04:11.582166+00:00 app[web.1]: 982 /app/vendor/bundle/ruby/2.2.0/gems/sprockets-3.6.0/lib/sprockets/sass_importer.rb
2016-05-10T03:04:11.582166+00:00 app[web.1]: 983 /app/vendor/bundle/ruby/2.2.0/gems/tilt-2.0.2/lib/tilt/mapping.rb
2016-05-10T03:04:11.582168+00:00 app[web.1]: 984 /app/vendor/bundle/ruby/2.2.0/gems/tilt-2.0.2/lib/tilt/template.rb
2016-05-10T03:04:11.582169+00:00 app[web.1]: 985 /app/vendor/bundle/ruby/2.2.0/gems/tilt-2.0.2/lib/tilt.rb
2016-05-10T03:04:11.582169+00:00 app[web.1]: 986 /app/vendor/bundle/ruby/2.2.0/gems/sass-rails-5.0.4/lib/sass/rails/importer.rb
2016-05-10T03:04:11.582172+00:00 app[web.1]: 987 /app/vendor/bundle/ruby/2.2.0/gems/sass-rails-5.0.4/lib/sass/rails/cache_store.rb
2016-05-10T03:04:11.582172+00:00 app[web.1]: 988 /app/vendor/bundle/ruby/2.2.0/gems/sass-rails-5.0.4/lib/sass/rails/template.rb
2016-05-10T03:04:11.582173+00:00 app[web.1]: 989 /app/vendor/bundle/ruby/2.2.0/gems/sass-rails-5.0.4/lib/sass/rails/logger.rb
2016-05-10T03:04:11.582175+00:00 app[web.1]: 990 /app/vendor/bundle/ruby/2.2.0/gems/sass-rails-5.0.4/lib/sass/rails/railtie.rb
2016-05-10T03:04:11.582175+00:00 app[web.1]: 991 /app/vendor/bundle/ruby/2.2.0/gems/sass-rails-5.0.4/lib/sass/rails.rb
2016-05-10T03:04:11.582176+00:00 app[web.1]: 992 /app/vendor/bundle/ruby/2.2.0/gems/sass-rails-5.0.4/lib/sass-rails.rb
2016-05-10T03:04:11.582178+00:00 app[web.1]: 993 /app/vendor/bundle/ruby/2.2.0/gems/execjs-2.6.0/lib/execjs/version.rb
2016-05-10T03:04:11.582178+00:00 app[web.1]: 994 /app/vendor/bundle/ruby/2.2.0/gems/execjs-2.6.0/lib/execjs/module.rb
2016-05-10T03:04:11.582179+00:00 app[web.1]: 995 /app/vendor/bundle/ruby/2.2.0/gems/execjs-2.6.0/lib/execjs/encoding.rb
2016-05-10T03:04:11.582182+00:00 app[web.1]: 996 /app/vendor/bundle/ruby/2.2.0/gems/execjs-2.6.0/lib/execjs/runtime.rb
2016-05-10T03:04:11.582182+00:00 app[web.1]: 997 /app/vendor/bundle/ruby/2.2.0/gems/execjs-2.6.0/lib/execjs/disabled_runtime.rb
2016-05-10T03:04:11.582183+00:00 app[web.1]: 998 /app/vendor/bundle/ruby/2.2.0/gems/execjs-2.6.0/lib/execjs/duktape_runtime.rb
2016-05-10T03:04:11.582185+00:00 app[web.1]: 999 /app/vendor/bundle/ruby/2.2.0/gems/execjs-2.6.0/lib/execjs/external_runtime.rb
2016-05-10T03:04:11.582186+00:00 app[web.1]: 1000 /app/vendor/bundle/ruby/2.2.0/gems/execjs-2.6.0/lib/execjs/ruby_racer_runtime.rb
2016-05-10T03:04:11.582187+00:00 app[web.1]: 1001 /app/vendor/bundle/ruby/2.2.0/gems/execjs-2.6.0/lib/execjs/ruby_rhino_runtime.rb
2016-05-10T03:04:11.582187+00:00 app[web.1]: 1002 /app/vendor/bundle/ruby/2.2.0/gems/execjs-2.6.0/lib/execjs/runtimes.rb
2016-05-10T03:04:11.582190+00:00 app[web.1]: 1003 /app/vendor/bundle/ruby/2.2.0/gems/execjs-2.6.0/lib/execjs.rb
2016-05-10T03:04:11.582190+00:00 app[web.1]: 1004 /app/vendor/bundle/ruby/2.2.0/gems/uglifier-3.0.0/lib/uglifier/version.rb
2016-05-10T03:04:11.582191+00:00 app[web.1]: 1005 /app/vendor/bundle/ruby/2.2.0/gems/uglifier-3.0.0/lib/uglifier.rb
2016-05-10T03:04:11.582194+00:00 app[web.1]: 1006 /app/vendor/bundle/ruby/2.2.0/gems/coffee-script-source-1.10.0/lib/coffee_script/source.rb
2016-05-10T03:04:11.582194+00:00 app[web.1]: 1007 /app/vendor/bundle/ruby/2.2.0/gems/coffee-script-2.4.1/lib/coffee_script.rb
アプリケーションで使用している C 拡張機能は判明しているため、原因が特定できるまでバックトレースをさかのぼって調査することができます。gem 名がシステム上の gem と異なる場合があることに注意してください。この場合、バックトレースの後半に unf_ext
を確認できます。
2016-05-10T03:04:11.590668+00:00 app[web.1]: 1346 /app/vendor/bundle/ruby/2.2.0/gems/unf-0.1.4/lib/unf/version.rb
2016-05-10T03:04:11.581498+00:00 app[web.1]: 517 /app/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.4/lib/active_support/core_ext/string/access.rb
2016-05-10T03:04:11.590669+00:00 app[web.1]: 1347 /app/vendor/bundle/ruby/2.2.0/gems/unf-0.1.4/lib/unf.rb
これは単なる例であり、このケースの原因は unf_ext
gem ではありませんでした。しかし、バックトレースに記録されているので、調査する価値はあります。
gem がセグメンテーション違反の原因であると判断した場合は、gem のメンテナーに問題を報告してください。セグメンテーション違反の完全なエラー出力を提供し、可能であれば常に、セグメンテーション違反を再現する小さなサンプルアプリケーションと再現方法の説明を含めてください。
“Gemfile の解析中にエラーが発生しました” セグメンテーション違反
環境変数 RUBY_THREAD_VM_STACK_SIZE
と Ruby buildpack の間の対話によってセグメンテーション違反が発生することがあります。セグメンテーション違反は次のようになります。
-----> Compiling Ruby/Rails
!
! There was an error parsing your Gemfile, we cannot continue
! /tmp/codon/tmp/buildpacks/50d5eddf222a9b7326028041d4e6509f915ccf2c/vendor/ruby/heroku-20/lib/ruby/3.0.0/x86_64-linux/enc/encdb.so: [BUG] Segmentation fault at 0x0000000000000018
! ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-linux]
!
! -- Control frame information -----------------------------------------------
! c:0002 p:-11861427355948 s:0006 e:000005 TOP [FINISH]
! c:0001 p:0000 s:0003 E:001870 (none) [FINISH]
エラーメッセージが There was an error parsing your Gemfile, we cannot continue
であることに注意してください。セグメンテーション違反の場所は encdb.so
の中です。また、この例外が buildpack によって Bundler バージョンが特定された後、Ruby バージョンが特定される前に発生することにも注意してください。
このセグメンテーション違反が発生する場合は、次の環境設定をアプリケーションから削除します。
$ heroku config:unset RUBY_THREAD_VM_STACK_SIZE
この例外は、Ruby buildpack が、自身で実行するバージョンの Ruby を使用するために発生します。2 月 24 日に、Heroku のエンジニアは、Ruby buildpack のバージョンを 2.7.5 から 3.0.3 にアップグレードしました。このバージョンの Ruby (3.0+) では、以前には発生しなかった RUBY_THREAD_VM_STACK_SIZE
内の値でセグメンテーション違反が発生します。解決策として、この環境変数を設定から削除します。