Posted at

【Rails】Unicorn5.3.0にはGC関連のバグがあるため5.3.1へアップデートする(`hash' called on hidden T_ARRAY objectエラーへの対処?)

More than 1 year has passed since last update.


はじめに

production環境のUnicornが不定期にアクセスできなくなる問題が発生しました。

Unicornのプロセスは起動しているものの、ブラウザでアクセスすると502が返されます。


環境


  • AWS

  • Ubuntu16.04

  • Unicorn 5.3.0

  • Rails 5.1

  • Ruby 2.4.1


発生したエラー

Unicorn.logには以下が出力されていました。

/home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_request.rb:80:in `parse': method `hash' called on hidden T_ARRAY object (0x0055645c4cf7a0 flags=0x1a067) (NotImplementedError)

from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_request.rb:80:in `read'
from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:606:in `process_client'

from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:702:in `worker_loop'
from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:549:in `spawn_missing_workers'

from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:563:in `maintain_worker_count'
from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:293:in `join'

from /home/ubuntu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/bin/unicorn_rails:209:in `<top (required)>'
from /home/ubuntu/.rbenv/versions/2.4.1/bin/unicorn_rails:22:in `load'

from /home/ubuntu/.rbenv/versions/2.4.1/bin/unicorn_rails:22:in `<main>'


考えられる原因

エラーログに出ているT_ARRAYという変数は、unicorn/bindings/ruby/unicorn_gem/ext/unicorn.c が使っている変数のようです(214行目)

https://github.com/unicorn-engine/unicorn/blob/master/bindings/ruby/unicorn_gem/ext/unicorn.c

213行目のUC_X86_REG_TRで調べてみると、UC_HOOK_MEM_FETCH_INVALIDの中にあり、

メモリのフェッチが無効?という事象のようです。。

http://cpansearch.perl.org/src/VIKAS/UnicornEngine-0.02/lib/UnicornEngine.pm

また、herokuで類似したエラーが出てる人がいました。

Google翻訳によると、以下が原因とのこと。


異なるRubyバージョンのオブジェクトからのバージョンの不一致

またはC拡張によって引き起こされるメモリの破損


unicorn Ruby/Rack server user+dev discussion/patches/pulls/bugs/help

また、Unicorn5.3.0にはGC関連の問題があるそうです。

unicorn 5.3.1 / 2017-10-03 19:03 UTC


unicorn 5.3.1 / 2017-10-03 19:03 UTC

This release fixes an occasional GC problem introduced in v5.3.0

to reduce global variable overhead (commit 979ebcf91705709b)

Thanks to Xuanzhong Wei for the patch which lead to this release:

https://bogomips.org/unicorn-public/20171003182054.76392-1-azrlew@gmail.com/T/#u

https://bogomips.org/unicorn-public/20171003145718.30404-1-azrlew@gmail.com/T/#u

Xuanzhong Wei (1):

fix GC issue on rb_global_variable array


上記を踏まえ、Unicornを5.3.1に更新することにしました。


事前準備

Gemfileのバージョンを固定化する。

  gem 'unicorn', '5.3.1'


アップデートの失敗例

bundle installで入れようとすると、lockファイルと違うと怒られるので注意。

$ bundle install --without development test staging

The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/.
You have requested:
unicorn = 5.3.1

The bundle currently has unicorn locked at 5.3.0.
Try running `bundle update unicorn`

If you are updating multiple gems in your Gemfile at once,
try passing them all to `bundle update`


アップデートの成功例

bundle update unicornで更新する。

$ bundle update unicorn

・・・略・・・
Fetching unicorn 5.3.1 (was 5.3.0)
Installing unicorn 5.3.1 (was 5.3.0) with native extensions


おわりに

これでひとまず様子を見てみることにします。

エラーが改善されることを期待します。