ohler55 / oj

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

segfault with ruby 2.4.2 #434

Closed skaes closed 6 years ago

skaes commented 6 years ago

The following code segfaults with ruby 2.4.2:

require 'oj'

S = Struct.new(
  :chunk_seq,
  :youngest,
  :oldest,
  :size
)

data = S.new(
  chunk_seq: 666000,
  youngest: nil,
  oldest: nil,
  size: 1
)

Oj.dump(data, mode: :object)

Removing any of the fields from the struct will cause it to not crash anymore.

Here's crash info:

oj_crash.rb:17: [BUG] Segmentation fault at 0x000000000000000c
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin16]

-- Crash Report log information --------------------------------------------
   See Crash Report log file under the one of following:                    
     * ~/Library/Logs/DiagnosticReports                                     
     * /Library/Logs/DiagnosticReports                                      
   for more details.                                                        
Don't forget to include the above Crash Report log file in bug reports.     

-- Control frame information -----------------------------------------------
c:0003 p:---- s:0013 e:000012 CFUNC  :dump
c:0002 p:0068 s:0007 E:000e88 EVAL   oj_crash.rb:17 [FINISH]
c:0001 p:0000 s:0003 E:000760 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
oj_crash.rb:17:in `<main>'
oj_crash.rb:17:in `dump'

-- Machine register context ------------------------------------------------
 rax: 0x000000000000000c rbx: 0x0000000000000004 rcx: 0x0000000000000000
 rdx: 0x0000000000000000 rdi: 0x0000000000000004 rsi: 0x0000000000000c61
 rbp: 0x00007fff5c174f40 rsp: 0x00007fff5c174ea0  r8: 0x0000000000000034
  r9: 0x0000000000000cf0 r10: 0x0000000111bd9110 r11: 0x0000000103b54a30
 r12: 0x0000000000000c61 r13: 0x0000000103cce305 r14: 0x0000000000000000
 r15: 0x0000000000000001 rip: 0x0000000103c40bc0 rfl: 0x0000000000010293

-- C level backtrace information -------------------------------------------
0   libruby.2.4.2.dylib                 0x0000000103c57f34 rb_vm_bugreport + 132
1   libruby.2.4.2.dylib                 0x0000000103af7423 rb_bug_context + 467
2   libruby.2.4.2.dylib                 0x0000000103bd7288 sigsegv + 72
3   libsystem_platform.dylib            0x00007fffc0385b3a _sigtramp + 26
4   libruby.2.4.2.dylib                 0x0000000103c40bc0 rb_check_funcall_default + 160
5   libruby.2.4.2.dylib                 0x0000000103b606d5 convert_type + 485
6   libruby.2.4.2.dylib                 0x0000000103b60b0b rb_to_int + 75
7   libruby.2.4.2.dylib                 0x0000000103b54a58 rb_num2long + 40
8   oj.bundle                           0x0000000103fcc808 dump_struct + 696
9   oj.bundle                           0x0000000103fc786b oj_dump_obj_to_json_using_params + 267
10  oj.bundle                           0x0000000103fdc56e dump + 190
11  libruby.2.4.2.dylib                 0x0000000103c4bd10 vm_call_cfunc + 272
12  libruby.2.4.2.dylib                 0x0000000103c365f0 vm_exec_core + 11504
13  libruby.2.4.2.dylib                 0x0000000103c46a64 vm_exec + 116
14  libruby.2.4.2.dylib                 0x0000000103b00268 ruby_exec_internal + 136
15  libruby.2.4.2.dylib                 0x0000000103b00186 ruby_run_node + 54
16  ruby                                0x0000000103a88f2f main + 79

-- Other runtime information -----------------------------------------------

* Loaded script: oj_crash.rb

* Loaded features:

    0 enumerator.so
    1 thread.rb
    2 rational.so
    3 complex.so
    4 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/x86_64-darwin16/enc/encdb.bundle
    5 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/x86_64-darwin16/enc/trans/transdb.bundle
    6 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/unicode_normalize.rb
    7 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/x86_64-darwin16/rbconfig.rb
    8 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/compatibility.rb
    9 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/defaults.rb
   10 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/deprecate.rb
   11 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/errors.rb
   12 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/version.rb
   13 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/requirement.rb
   14 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/platform.rb
   15 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/basic_specification.rb
   16 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/stub_specification.rb
   17 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/util/list.rb
   18 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/x86_64-darwin16/stringio.bundle
   19 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/specification.rb
   20 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/exceptions.rb
   21 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/dependency.rb
   22 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/core_ext/kernel_gem.rb
   23 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/monitor.rb
   24 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb
   25 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems.rb
   26 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/rubygems/path_support.rb
   27 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean/version.rb
   28 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean/core_ext/name_error.rb
   29 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean/levenshtein.rb
   30 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean/jaro_winkler.rb
   31 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean/spell_checker.rb
   32 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/delegate.rb
   33 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb
   34 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb
   35 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean/spell_checkers/name_error_checkers.rb
   36 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean/spell_checkers/method_name_checker.rb
   37 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean/spell_checkers/null_checker.rb
   38 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean/formatter.rb
   39 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@global/gems/did_you_mean-1.1.0/lib/did_you_mean.rb
   40 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/x86_64-darwin16/bigdecimal.bundle
   41 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@activities/gems/oj-3.3.5/lib/oj/version.rb
   42 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@activities/gems/oj-3.3.5/lib/oj/bag.rb
   43 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@activities/gems/oj-3.3.5/lib/oj/easy_hash.rb
   44 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@activities/gems/oj-3.3.5/lib/oj/error.rb
   45 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/ostruct.rb
   46 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@activities/gems/oj-3.3.5/lib/oj/mimic.rb
   47 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@activities/gems/oj-3.3.5/lib/oj/saj.rb
   48 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@activities/gems/oj-3.3.5/lib/oj/schandler.rb
   49 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/x86_64-darwin16/date_core.bundle
   50 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/date.rb
   51 /Users/stefan.kaes/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/time.rb
   52 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@activities/gems/oj-3.3.5/lib/oj/oj.bundle
   53 /Users/stefan.kaes/.rvm/gems/ruby-2.4.2@activities/gems/oj-3.3.5/lib/oj.rb

It worked with 2.4.1 This is kinda a big deal because 2.4.1 has security issues which basically forces us to upgrade to 2.4.2.

skaes commented 6 years ago

I'm trying to figure out what's going on but apparently the code freaks out so much it overwrites the stack in such a way that gdb cannot produce a proper stack trace. Or my ruby is compiled without frame pointer or something like that.

skaes commented 6 years ago

FYI, ruby 2.3.5 does not crash.

ohler55 commented 6 years ago

I'll look into it. I think I know what it might be though. 2.4.2 changes RSTRUCT_LEN in a very fundamental way. One returns a VALUE (Ruby object) and one returns an integer.

ohler55 commented 6 years ago

I hadn't pushed a release that should have happened a week or two ago. 3.3.6 has been release with the fixes.

skaes commented 6 years ago

I have updated to 3.3.6 and this particular crash has been fixed. However, it still keeps crashing and tests are failing where struct fields contain nonsense value of completely unexpected type after converting from structs to json and back (all fine with ruby 2.3.5). Unfortunately, the errors appear to be random, so I have no simple test case to reproduce the error in a simpler context. Working on it.

skaes commented 6 years ago

@ohler55 BTW: thx for the quick response!

ohler55 commented 6 years ago

Sounds like a different problem. If you can get something that crashes every once in a while I can keep running it.

skaes commented 6 years ago

After reinstalling ruby and all gems the crashes disappeared. Oj seems fine for 2.4.2 usage now. Thx a lot.

ohler55 commented 6 years ago

Good to hear.