rubyomr-preview / ruby

The Ruby+OMR Preview
Other
68 stars 9 forks source link

me->def != NULL, but not dereferenceable (@warm) #61

Open mgaudet opened 7 years ago

mgaudet commented 7 years ago

I'm seeing intermittent crashes in a number of scenarios when running with optLevel=warm regarding the method entry definition being non-null, but also not dereferenceable. The stack traces are always something like this:

/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(rb_vm_bugreport+0x53e) [0x55aa84ab19ce] vm_dump.c:685
/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(rb_bug_context+0xd1) [0x55aa84aa69d1] error.c:426
/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(sigsegv+0x3e) [0x55aa8499cffe] signal.c:907
/lib/x86_64-linux-gnu/libpthread.so.0 [0x7fc2d9f263d0]
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(TR_InlinerBase::checkInlineableWithoutInitialCalleeSymbol(TR_CallSite*, TR::Compilation*)+0x36d) [0x7fc2d82f66b5] /home/magaudet/open/ruby_Inliner/rbjitglue/ruby/optimizer/RubyInliner.cpp:260
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(TR_InlinerBase::getSymbolAndFindInlineTargets(TR_CallStack*, TR_CallSite*, bool)+0x2c8) [0x7fc2d832bcfc] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/Inliner.cpp:3824
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(TR_DumbInliner::analyzeCallSite(TR_CallStack*, TR::TreeTop*, TR::Node*, TR::Node*)+0x11d) [0x7fc2d83210ad] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/Inliner.cpp:1287
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(TR_DumbInliner::inlineCallTargets(TR::ResolvedMethodSymbol*, TR_CallStack*, TR_InnerPreexistenceInfo*)+0x551) [0x7fc2d8320df3] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/Inliner.cpp:1249
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(TR_InlinerBase::performInlining(TR::ResolvedMethodSymbol*)+0xe4) [0x7fc2d831d8e0] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/Inliner.cpp:419
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(Ruby::TrivialInliner::perform()+0x10f) [0x7fc2d82f7245] /home/magaudet/open/ruby_Inliner/rbjitglue/ruby/optimizer/RubyTrivialInliner.cpp:48
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(OMR::Optimizer::performOptimization(OptimizationStrategy const*, int, int, int)+0x2a2d) [0x7fc2d839244d] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/OMROptimizer.cpp:2007
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(OMR::Optimizer::optimize()+0x88b) [0x7fc2d838f14d] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/OMROptimizer.cpp:1106
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(OMR::Compilation::performOptimizations()+0x139) [0x7fc2d81f99ab] /home/magaudet/open/ruby_Inliner/omr/compiler/compile/OMRCompilation.cpp:1093
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(OMR::Compilation::compile()+0x92b) [0x7fc2d81f92bd] /home/magaudet/open/ruby_Inliner/omr/compiler/compile/OMRCompilation.cpp:882
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(compileMethodFromDetails(OMR_VMThread*, TR::IlGeneratorMethodDetails&, TR_Hotness, int&)+0x618) [0x7fc2d8185776] /home/magaudet/open/ruby_Inliner/omr/compiler/control/CompileMethod.cpp:340
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(compileMethod(OMR_VMThread*, TR_ResolvedMethod&, TR_Hotness, int&)+0x59) [0x7fc2d8185113] /home/magaudet/open/ruby_Inliner/omr/compiler/control/CompileMethod.cpp:235
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(compileRubyISeq(rb_iseq_struct*, char const*, TR_Hotness)+0x7a) [0x7fc2d81881fa] /home/magaudet/open/ruby_Inliner/rbjitglue/ruby/control/RubyJit.cpp:281
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(jit_compile+0x3f8) [0x7fc2d8188652] /home/magaudet/open/ruby_Inliner/rbjitglue/ruby/control/RubyJit.cpp:386
/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(vm_jit.isra.101+0x2d) [0x55aa84a07aed] vm_insnhelper.c:2851
/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(vm_exec+0x85e) [0x55aa84a18dfe] vm.c:1729
/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(vm_send_without_block+0x8e) [0x55aa84a1aeae] vm_insnhelper.c:2971
[0x7fc2cf8faa78]/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(rb_vm_bugreport+0x53e) [0x55aa84ab19ce] vm_dump.c:685
/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(rb_bug_context+0xd1) [0x55aa84aa69d1] error.c:426
/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(sigsegv+0x3e) [0x55aa8499cffe] signal.c:907
/lib/x86_64-linux-gnu/libpthread.so.0 [0x7fc2d9f263d0]
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(TR_InlinerBase::checkInlineableWithoutInitialCalleeSymbol(TR_CallSite*, TR::Compilation*)+0x36d) [0x7fc2d82f66b5] /home/magaudet/open/ruby_Inliner/rbjitglue/ruby/optimizer/RubyInliner.cpp:260
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(TR_InlinerBase::getSymbolAndFindInlineTargets(TR_CallStack*, TR_CallSite*, bool)+0x2c8) [0x7fc2d832bcfc] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/Inliner.cpp:3824
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(TR_DumbInliner::analyzeCallSite(TR_CallStack*, TR::TreeTop*, TR::Node*, TR::Node*)+0x11d) [0x7fc2d83210ad] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/Inliner.cpp:1287
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(TR_DumbInliner::inlineCallTargets(TR::ResolvedMethodSymbol*, TR_CallStack*, TR_InnerPreexistenceInfo*)+0x551) [0x7fc2d8320df3] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/Inliner.cpp:1249
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(TR_InlinerBase::performInlining(TR::ResolvedMethodSymbol*)+0xe4) [0x7fc2d831d8e0] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/Inliner.cpp:419
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(Ruby::TrivialInliner::perform()+0x10f) [0x7fc2d82f7245] /home/magaudet/open/ruby_Inliner/rbjitglue/ruby/optimizer/RubyTrivialInliner.cpp:48
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(OMR::Optimizer::performOptimization(OptimizationStrategy const*, int, int, int)+0x2a2d) [0x7fc2d839244d] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/OMROptimizer.cpp:2007
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(OMR::Optimizer::optimize()+0x88b) [0x7fc2d838f14d] /home/magaudet/open/ruby_Inliner/omr/compiler/optimizer/OMROptimizer.cpp:1106
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(OMR::Compilation::performOptimizations()+0x139) [0x7fc2d81f99ab] /home/magaudet/open/ruby_Inliner/omr/compiler/compile/OMRCompilation.cpp:1093
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(OMR::Compilation::compile()+0x92b) [0x7fc2d81f92bd] /home/magaudet/open/ruby_Inliner/omr/compiler/compile/OMRCompilation.cpp:882
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(compileMethodFromDetails(OMR_VMThread*, TR::IlGeneratorMethodDetails&, TR_Hotness, int&)+0x618) [0x7fc2d8185776] /home/magaudet/open/ruby_Inliner/omr/compiler/control/CompileMethod.cpp:340
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(compileMethod(OMR_VMThread*, TR_ResolvedMethod&, TR_Hotness, int&)+0x59) [0x7fc2d8185113] /home/magaudet/open/ruby_Inliner/omr/compiler/control/CompileMethod.cpp:235
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(compileRubyISeq(rb_iseq_struct*, char const*, TR_Hotness)+0x7a) [0x7fc2d81881fa] /home/magaudet/open/ruby_Inliner/rbjitglue/ruby/control/RubyJit.cpp:281
/home/magaudet/.rbenv/versions/ruby_2_4_omr/lib/librbjit.so(jit_compile+0x3f8) [0x7fc2d8188652] /home/magaudet/open/ruby_Inliner/rbjitglue/ruby/control/RubyJit.cpp:386
/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(vm_jit.isra.101+0x2d) [0x55aa84a07aed] vm_insnhelper.c:2851
/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(vm_exec+0x85e) [0x55aa84a18dfe] vm.c:1729
/home/magaudet/.rbenv/versions/ruby_2_4_omr/bin/ruby(vm_send_without_block+0x8e) [0x55aa84a1aeae] vm_insnhelper.c:2971
[0x7fc2cf8faa78]

We are peeking inside the call cache at this point, to see if we can't find ourselves an inlinable target.

The rough outline of the code is something like this:

   CALL_CACHE cc = <load call cache>;
   const rb_callable_method_entry_t *me = cc->me;
   if(!me)
      {
      // abort 
      }

   if (!me->def)
      {
      // abort 
      }

   switch (METHOD_ENTRY_VISI(cc->me))
      {
      case METHOD_VISI_PUBLIC:
         break; // OK for inlining.
      case METHOD_VISI_PRIVATE:
         if (ci->flag & VM_CALL_FCALL)
            break; // Ok for inlining
      default:
         //abort 
      }

   switch(me->def->type) // Crashes here de-referencing me->def 
      {
      // ...
      }

So it seems there's something missing here.

One thing I'm considering is that I'm attempting to inline a collected method -- and so really, what I've been inspecting is garbage.

mgaudet commented 7 years ago

Have seen running RubySpec under repetition: OMR_JIT_OPTIONS=-Xjit:count=1,optLevel=warm LD_LIBRARY_PATH=$PWD ./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems -r./x86_64-linux-fake ./spec/mspec/bin/mspec run -R3 -B ./spec/default.mspec

mgaudet commented 7 years ago

Sent up a request for help to ruby-core here