ohler55 / oj

Optimized JSON
http://www.ohler.com/oj
MIT License
3.14k stars 251 forks source link

Segfault in 3.13.23 when attempting to benchmark :saj #838

Closed copiousfreetime closed 1 year ago

copiousfreetime commented 1 year ago

Problem

I am attempting to do some benchmarking of :saj vs.:usual vs Doc vs. Oj.load and managed to get a segfault in linux. I've boiled it down to the following script and run it with bundle exec ruby ./crash-oj.rb.

The key seems to be allocating a:saj parser (and not even using it) and using load - I'm pretty sure this is a GC issue as it only crashes after the Oj.load has been called thousands of times.

crash-oj.rb

require 'oj'

p = Oj::Parser.new(:saj)

json = %|{
        "array": [
                {
                        "num"   : 3,
                        "string": "message",
                        "hash"  : {
                                "h2"  : {
                                        "a" : [ 1, 2, 3 ]
                                }
                        }
                }
        ],
        "boolean" : true
}|

100_000.times do
  e = Oj.load(json)
end

Environment

Bundler       2.4.3
  Platforms   ruby, x86_64-linux
Ruby          2.7.7p221 (2022-11-24 revision 168ec2b1e5ad0e4688e963d9de019557c78feed9) [x86_64-linux]
  Full Path   /opt/rbenv/versions/2.7.7/bin/ruby
  Config Dir  /opt/rbenv/versions/2.7.7/etc
RubyGems      3.1.6
  Gem Home    /opt/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0
  Gem Path    /home/navpass/.gem/ruby/2.7.0:/opt/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0
  User Home   /home/navpass
  User Path   /home/navpass/.gem/ruby/2.7.0
  Bin Dir     /opt/rbenv/versions/2.7.7/bin
Tools
  Git         2.25.1
  RVM         not installed
  rbenv       rbenv 1.2.0
  chruby      not installed

Bundler Build Metadata

Built At          2023-01-06
Git SHA           ed1f27f75c
Released Version  true

Bundler settings

path
  Set for your local app (/ebs/tmp/scratch/2023_oj-bench/.bundle/config): "./vendor"

Gemfile

Gemfile

source 'https://rubygems.org'
gem 'benchmark-ips'
gem 'oj'

Gemfile.lock

GEM
  remote: https://rubygems.org/
  specs:
    benchmark-ips (2.10.0)
    oj (3.13.23)

PLATFORMS
  x86_64-linux

DEPENDENCIES
  benchmark-ips
  oj

BUNDLED WITH
   2.4.3
ohler55 commented 1 year ago

I'll take a look and see what is going on.

ohler55 commented 1 year ago

I grabbed the file and tested on macOS as well as linux with ruby 3.1 and 2.7.7 and could not get a crash even after bumping the iterations to 1M. The one difference was I did not use benchmark-ips since it didn't seem to be used. I also tried bundle exec ruby ./crash-oj.rb without a failure. I was also using the develop branch so I made a release, v3.14.0. Please try that and see if you still have the issue. If you do then we'll have to look for what else might be different in our environments.

ohler55 commented 1 year ago

Update:

When running with 10M iterations I was able to get a crash after half a dozen runs. I was also able to replicate a crash with ruby 3.1.0 after 11 runs.

ohler55 commented 1 year ago

Found it!

ohler55 commented 1 year ago

Please try the develop branch and see if it is fixed for you.

copiousfreetime commented 1 year ago

Yup, works for me - and I've run some benchmarks - with surprising to me results - will open an issue to make sure I'm doing this benchmark correctly.

ohler55 commented 1 year ago

released v3.14.1