Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8324883

[premain] Crash in Method::get_c2i_entry() in final step of 5-step workflow

XMLWordPrintable

      With 5-step workflow following crash is observed in the final step:

      #
      # A fatal error has been detected by the Java Runtime Environment:
      #
      # SIGSEGV (0xb) at pc=0x00007f4f373043b4, pid=3775928, tid=3775929
      #
      # JRE version: OpenJDK Runtime Environment (23.0) (build 23-internal-adhoc.asmehra.leyden)
      # Java VM: OpenJDK 64-Bit Server VM (23-internal-adhoc.asmehra.leyden, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
      # Problematic frame:
      # V [libjvm.so+0xd043b4] Method::get_c2i_entry()+0x4
      #
      # Core dump will be written. Default location: /home/asmehra/data/ashu-mehra/leyden-perf/quarkus-hibernate-orm-quickstart/core.3775928
      #
      # If you would like to submit a bug report, please visit:
      # https://bugreport.java.com/bugreport/crash.jsp


      Stack: [0x00007f4f36500000,0x00007f4f36600000], sp=0x00007f4f365faf08, free space=1003k
      Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
      V [libjvm.so+0xd043b4] Method::get_c2i_entry()+0x4 (method.cpp:157)
      V [libjvm.so+0xe4dc68] SharedRuntime::resolve_sub_helper_internal(methodHandle, frame const&, CompiledMethod*, bool, bool, Handle, CallInfo&, Bytecodes::Code, JavaThread*)+0x108 (sharedRuntime.cpp:1381)
      V [libjvm.so+0xe52800] SharedRuntime::resolve_sub_helper(bool, bool, JavaThread*)+0x2a0 (sharedRuntime.cpp:1528)
      V [libjvm.so+0xe52927] SharedRuntime::resolve_helper(bool, bool, JavaThread*)+0x37 (sharedRuntime.cpp:1329)
      V [libjvm.so+0xe52f20] SharedRuntime::resolve_opt_virtual_call_C(JavaThread*)+0x70 (sharedRuntime.cpp:1722)
      v ~RuntimeStub::resolve_opt_virtual_call 0x00007f4f1ff853fb
      J 532 c1 java.lang.Class.forName(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class; java.base@23-internal (150 bytes) @ 0x00007f4f18a7c904 [0x00007f4f18a7c3e0+0x0000000000000524]


      gdb shows following backtrace:

      #10 0x00007f4f373043b4 in Method::get_c2i_entry (this=this@entry=0x80007a8c0) at src/hotspot/share/oops/method.cpp:157
      #11 0x00007f4f36cadba1 in CompiledIC::compute_monomorphic_entry (method=..., receiver_klass=0x800079f90, is_optimized=is_optimized@entry=true, static_bound=<optimized out>, caller_is_nmethod=caller_is_nmethod@entry=true, info=...,
          __the_thread__=0x7f4f3001a150) at src/hotspot/share/code/compiledIC.cpp:549
       #12 0x00007f4f3744dc68 in SharedRuntime::resolve_sub_helper_internal (callee_method=..., caller_frame=..., caller_nm=caller_nm@entry=0x7f4f18a7c110, is_virtual=is_virtual@entry=true, is_optimized=is_optimized@entry=true, receiver=...,
          receiver@entry=..., call_info=..., invoke_code=Bytecodes::_invokespecial, __the_thread__=0x7f4f3001a150) at src/hotspot/share/runtime/sharedRuntime.cpp:1381
      #13 0x00007f4f37452800 in SharedRuntime::resolve_sub_helper (is_virtual=is_virtual@entry=true, is_optimized=is_optimized@entry=true, __the_thread__=__the_thread__@entry=0x7f4f3001a150) at src/hotspot/share/runtime/sharedRuntime.cpp:1528
      #14 0x00007f4f37452927 in SharedRuntime::resolve_helper (is_virtual=is_virtual@entry=true, is_optimized=is_optimized@entry=true, __the_thread__=__the_thread__@entry=0x7f4f3001a150) at src/hotspot/share/runtime/sharedRuntime.cpp:1329
      #15 0x00007f4f37452f20 in SharedRuntime::resolve_opt_virtual_call_C (current=0x7f4f3001a150) at src/hotspot/share/runtime/sharedRuntime.cpp:1722

      Dumping the method shows Method::_adapter is null which caused the crash.
      (gdb) p *(Method *)0x80007a8c0
      $1 = {
        <Metadata> = {
          <MetaspaceObj> = {
            static _shared_metaspace_base = 0x800000000,
            static _shared_metaspace_top = 0x803a22000
          },
          members of Metadata:
          _vptr.Metadata = 0x800000790
        },
        members of Method:
        _constMethod = 0x801e86120,
        _method_data = 0x0,
        _method_counters = 0x0,
        _adapter = 0x0,
        _access_flags = {
          _flags = 1
        },
        _vtable_index = -2,
        _flags = {
          _status = 16384
        },
        _intrinsic_id = 0,
        _trace_flags = {
          _flags = 0
        },
        _i2i_entry = 0x0,
        _from_compiled_entry = 0x0,
        _code = 0x0,
        _from_interpreted_entry = 0x0,
        _preload_code = 0x0,
        _scc_entry = 0x0
      }


      The crash originated from C1 compiled code for Class::forName when it tried to call ClassNotFoundException.<init> at 0x00007f4f18a7c8ff:

        0x00007f4f18a7c890: movabs $0x800079f90,%rdx ; {metadata('java/lang/ClassNotFoundException')}
        0x00007f4f18a7c89a: mov 0x1b8(%r15),%rax
        0x00007f4f18a7c8a1: lea 0x28(%rax),%rdi
        0x00007f4f18a7c8a5: cmp 0x1c8(%r15),%rdi
        0x00007f4f18a7c8ac: ja 0x00007f4f18a7ca18
        0x00007f4f18a7c8b2: mov %rdi,0x1b8(%r15)
        0x00007f4f18a7c8b9: movq $0x1,(%rax)
        0x00007f4f18a7c8c0: mov %rdx,%rcx
        0x00007f4f18a7c8c3: movabs $0x800000000,%r10
        0x00007f4f18a7c8cd: sub %r10,%rcx
        0x00007f4f18a7c8d0: mov %ecx,0x8(%rax)
        0x00007f4f18a7c8d3: xor %rcx,%rcx
        0x00007f4f18a7c8d6: mov %ecx,0xc(%rax)
        0x00007f4f18a7c8d9: xor %rcx,%rcx
        0x00007f4f18a7c8dc: mov %rcx,0x10(%rax)
        0x00007f4f18a7c8e0: mov %rcx,0x18(%rax)
        0x00007f4f18a7c8e4: mov %rcx,0x20(%rax)
        0x00007f4f18a7c8e8: mov 0x80(%rsp),%rdx
        0x00007f4f18a7c8f0: mov %rax,%rsi
        0x00007f4f18a7c8f3: mov %rax,0xb8(%rsp)
        0x00007f4f18a7c8fb: nopl 0x0(%rax)
        0x00007f4f18a7c8ff: call 0x00007f4f1ff85380 ; ImmutableOopMap {[120]=Oop [184]=Oop }
                                                                  ;*invokespecial <init> {reexecute=0 rethrow=0 return_oop=0}
                                                                  ; - java.lang.Class::forName@72 (line 525)
                                                                  ; {optimized virtual_call}
        0x00007f4f18a7c904: nopl 0xe0007f4(%rax,%rax,1) ; {other}

        
      The InstanceKlass pointer used by movabs instruction at 0x00007f4f18a7c890 is actually patched at runtime. The un-patched version of the code loaded from the shared code archive is:

        0x00007f4f18a7c890: jmp 0x00007f4f18a7ca0e ; {no_reloc}
        0x00007f4f18a7c895: add %al,(%rax)
        0x00007f4f18a7c897: add %al,(%rax)
        0x00007f4f18a7c899: add %cl,-0x75(%rcx)
        0x00007f4f18a7c89c: xchg %edi,0x48000001(%rax)
        0x00007f4f18a7c8a2: lea 0x28(%rax),%edi
        0x00007f4f18a7c8a5: cmp 0x1c8(%r15),%rdi
        0x00007f4f18a7c8ac: ja 0x00007f4f18a7ca18
        0x00007f4f18a7c8b2: mov %rdi,0x1b8(%r15)
        0x00007f4f18a7c8b9: movq $0x1,(%rax)
        0x00007f4f18a7c8c0: mov %rdx,%rcx
        0x00007f4f18a7c8c3: movabs $0x800000000,%r10
        0x00007f4f18a7c8cd: sub %r10,%rcx
        0x00007f4f18a7c8d0: mov %ecx,0x8(%rax)
        0x00007f4f18a7c8d3: xor %rcx,%rcx
        0x00007f4f18a7c8d6: mov %ecx,0xc(%rax)
        0x00007f4f18a7c8d9: xor %rcx,%rcx
        0x00007f4f18a7c8dc: mov %rcx,0x10(%rax)
        0x00007f4f18a7c8e0: mov %rcx,0x18(%rax)
        0x00007f4f18a7c8e4: mov %rcx,0x20(%rax)
        0x00007f4f18a7c8e8: mov 0x80(%rsp),%rdx
        0x00007f4f18a7c8f0: mov %rax,%rsi
        0x00007f4f18a7c8f3: mov %rax,0xb8(%rsp)
        0x00007f4f18a7c8fb: nopl 0x0(%rax)
        0x00007f4f18a7c8ff: call 0x00007f4f1ff85380 ; ImmutableOopMap {[120]=Oop [184]=Oop }
                                                                  ;*invokespecial <init> {reexecute=0 rethrow=0 return_oop=0}
                                                                  ; - java.lang.Class::forName@72 (line 525)
                                                                  ; {optimized virtual_call}

      Code at 0x00007f4f18a7ca0e is a call to runtime stub load_klass_patching which loads the class and patches the compiled code with the InstanceKlass pointer.

        0x00007f4f18a7ca0e: call 0x00007f4f20111200 ; ImmutableOopMap {[120]=Oop [128]=Oop }
                                                                  ;*new {reexecute=1 rethrow=0 return_oop=0}
                                                                  ; - (reexecute) java.lang.Class::forName@67 (line 525)
                                                                  ; {runtime_call load_klass_patching Runtime1 stub}
        0x00007f4f18a7ca13: jmp 0x00007f4f18a7c890
        
      The loading and patching is done by Runtime1::patch_code where it handles various bytecodes including Bytecodes::_new.
      Runtime1::patch_code loads the class by calling SystemDictionary::resolve_or_fail().

      This code was actually generated in the previous run of the application that generated the shared code archive.
      In that run of the application, when the Class::forName was compiled by C1, ClassNotFoundException was already loaded and initialized but
      the constant pool entry used by the new bytecode in java.lang.Class::forName referring to the ClassNotFoundException was not resolved. As a result the code for patching the class was generated.

      Now, in normal scenario the C1 code that handles subsequent call to allocate object would have ensured the class is initialized.
      This is done in LIR_Assembler::emit_alloc_obj() (fast path) which has init check and Runtime1::new_instance (slow path).
      The check in fast path LIR_Assembler::emit_alloc_obj() is done at code generation time during which ClassNotFoundException was already initialized,
      therefore the init check in LIR_Assembler::emit_alloc_obj() was skipped.
      Now, under normal scenario this would have worked fine, as the fact that ClassNotFoundException is initialized does not change between code generation and code execution in the same run of the application.
      However, since this code is stored in shared code archive, it gets loaded in the next run of the application and it so happened that by the time the code is executed, the ClassNotFoundException has not been initialized.
      This results in the uninitialized adapters in the methods of ClassNotFoundException leading to the above crash.

            Unassigned Unassigned
            asmehra Ashutosh Mehra
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: