oj: oj gem 3.13.15+ causes an illegal instruction on CPUs that do not support SSE4.2

After the introduction of cmpestri in a455c389c0bd09cb591d1144e9366fc3f3280da0, people with CPUs that do not support SSE4.2 cannot use the gem.

We have multiple reports of ruby abending with an Illegal Instruction from users of Discourse:

https://meta.discourse.org/t/discourse-update-keeps-failing/231862/25?u=supermathie

https://meta.discourse.org/t/discourse-update-keeps-failing/231862/33?u=supermathie

Can we add a runtime check here to ensure the instruction is supported prior to using it?

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 4
  • Comments: 17 (9 by maintainers)

Commits related to this issue

Most upvoted comments

v3.13.20 is out now and disables this by default: https://github.com/ohler55/oj/pull/806

If you need this optimization, compile the gem with the --with-sse42 flag.

We are also seeing many reports of this upon upgrading to 3.13.16: https://gitlab.com/gitlab-org/gitlab/-/issues/368656

I may have spoken too soon. It seems that with the -msse42 flag, the .so contains other SSE instructions that may not be available. Using https://github.com/pkgw/elfx86exts/releases, we see:

$ ./elfx86exts /opt/gitlab/embedded/lib/ruby/gems/2.7.0/gems/oj-3.13.19/lib/oj/oj.so
MODE64 (call)
CMOV (cmovne)
SSE2 (movq)
SSE41 (pinsrq)
SSE1 (movups)
SSSE3 (pshufb)
SSE3 (movddup)
SSE42 (pcmpestri)
CPU Generation: Unknown

Without the -msse4.2 flag, we get:

MODE64 (call)
SSE2 (pxor)
SSE1 (movups)
CMOV (cmovl)
CPU Generation: Intel Core

So it seems we may need to have a flag that disables -msse42 outright here.

I think we can close this issue. I’ve received confirmation from users with x86 hardware without SSE instructions that 3.3.18 solves the problem.

I’ve also verified that 3.3.18 properly enables SSE 4.2 for x86 on Linux and macOS, while leaves it off for macOS arm64 platforms.

How about an environment variable that is checked in extconf.rb to block use of SSE4.2?

@Watson1978 can you look into this?