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

Concurrent implicit attach from native threads crashes VM

XMLWordPrintable

    • b28
    • x86_64
    • linux
    • Verified

        ADDITIONAL SYSTEM INFORMATION :
        Linux, JDK 19-ea+23-1706

        A DESCRIPTION OF THE PROBLEM :
        Using the Foreign Function & Memory API to call a native C++ function which calls back into the JVM concurrently (at least two C++ threads) causes the JVM to crash. The same program (modulo some changes to make it compilable with JDK 19) worked on JVM 18.

        # A fatal error has been detected by the Java Runtime Environment:
        #
        # SIGSEGV (0xb) at pc=0x00007fec8d25e842, pid=7636, tid=7655
        #
        # JRE version: OpenJDK Runtime Environment (19.0+23) (build 19-ea+23-1706)
        # Java VM: OpenJDK 64-Bit Server VM (19-ea+23-1706, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
        # Problematic frame:
        # V [libjvm.so+0x85e842] java_lang_Thread::set_thread_status(oopDesc*, JavaThreadStatus)+0x22

        --------------- S U M M A R Y ------------

        Command Line: --enable-preview --enable-native-access=ALL-UNNAMED JavaClass

        Host: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz, 8 cores, 7G, Manjaro Linux
        Time: Wed May 25 13:58:14 2022 CEST elapsed time: 0.110217 seconds (0d 0h 0m 0s)

        --------------- T H R E A D ---------------

        Current thread (0x00007fec18000bf0): JavaThread "<no-name - thread is attaching>"
        [error occurred during error reporting (printing current thread), id 0xb, SIGSEGV (0xb) at pc=0x00007fec8d25e78c]

        Stack: [0x00007fec23801000,0x00007fec24000000], sp=0x00007fec23ffe160, free space=8180k
        Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
        V [libjvm.so+0x85e842] java_lang_Thread::set_thread_status(oopDesc*, JavaThreadStatus)+0x22
        V [libjvm.so+0xc4132b] ObjectMonitor::INotify(JavaThread*)+0x13b
        V [libjvm.so+0xc4275f] ObjectMonitor::notifyAll(JavaThread*)+0x8f
        V [libjvm.so+0x82dbee] InstanceKlass::set_initialization_state_and_notify(InstanceKlass::ClassState, JavaThread*)+0xae
        V [libjvm.so+0x836ea8] InstanceKlass::initialize_impl(JavaThread*)+0x738
        V [libjvm.so+0xad5a9a] LinkResolver::resolve_static_call(CallInfo&, LinkInfo const&, bool, JavaThread*)+0x16a
        V [libjvm.so+0xad64cb] LinkResolver::resolve_invoke(CallInfo&, Handle, constantPoolHandle const&, int, Bytecodes::Code, JavaThread*)+0x2bb
        V [libjvm.so+0x8538b7] InterpreterRuntime::resolve_invoke(JavaThread*, Bytecodes::Code)+0x177
        V [libjvm.so+0x853e37] InterpreterRuntime::resolve_from_cache(JavaThread*, Bytecodes::Code)+0x37
        j java.lang.Thread.genThreadName()Ljava/lang/String;+13 java.base@19-ea
        j java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/Runnable;)V+2 java.base@19-ea
        v ~StubRoutines::call_stub 0x00007fec78537cc6
        V [libjvm.so+0x8589f5] JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x315
        V [libjvm.so+0x85a01a] JavaCalls::call_special(JavaValue*, Handle, Klass*, Symbol*, Symbol*, Handle, Handle, JavaThread*)+0x1aa
        V [libjvm.so+0xe11612] JavaThread::allocate_threadObj(Handle, char const*, bool, JavaThread*)+0xc2
        V [libjvm.so+0x9042aa] attach_current_thread.part.0+0x19a
        V [libjvm.so+0xe3e02b] ProgrammableUpcallHandler::on_entry(OptimizedEntryBlob::FrameData*)+0x15b
        v blob 0x00007fec78661b91
        C [libffm.so+0x3514] f(char const* (*)())+0x1b
        C [libffm.so+0x3eb8] void std::__invoke_impl<void, void (*)(char const* (*)()), char const* (*)()>(std::__invoke_other, void (*&&)(char const* (*)()), char const* (*&&)())+0x34
        C [libffm.so+0x3e2d] std::__invoke_result<void (*)(char const* (*)()), char const* (*)()>::type std::__invoke<void (*)(char const* (*)()), char const* (*)()>(void (*&&)(char const* (*)()), char const* (*&&)())+0x37
        C [libffm.so+0x3d9d] void std::thread::_Invoker<std::tuple<void (*)(char const* (*)()), char const* (*)()> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>)+0x43
        C [libffm.so+0x3d56] std::thread::_Invoker<std::tuple<void (*)(char const* (*)()), char const* (*)()> >::operator()()+0x18
        C [libffm.so+0x3d3a] std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(char const* (*)()), char const* (*)()> > >::_M_run()+0x1c

        Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
        j java.lang.Thread.genThreadName()Ljava/lang/String;+13 java.base@19-ea
        j java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/Runnable;)V+2 java.base@19-ea
        v ~StubRoutines::call_stub 0x00007fec78537cc6

        siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000000018

        [abridged -- see hs_err.txt in attachment]

        REGRESSION : Last worked in version 18.0.1
        FREQUENCY : often
        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        $ g++ -fPIC -shared -o libffm.so nativemethod.cpp
        $ javac --enable-preview -source 19 JavaClass.java
        $ LD_LIBRARY_PATH=. java --enable-preview --enable-native-access=ALL-UNNAMED JavaClass

        ---------- BEGIN SOURCE ----------
        nativemethod.cpp:

        #include <iostream>
        #include <thread>

        using namespace std;

        extern "C" {
        void nativeMethod(const char* (*) ());
        }

        void f(const char* getMessage()) {
          for (auto i = 0; i < 100; ++i)
            cout << getMessage() << endl;
        };

        void nativeMethod(const char* getMessage()) {
          auto t1 = thread{f, getMessage};
          auto t2 = thread{f, getMessage};
          t1.join();
          t2.join();
        }

        JavaClass.java:

        import java.lang.foreign.Addressable;
        import java.lang.foreign.FunctionDescriptor;
        import java.lang.foreign.Linker;
        import java.lang.foreign.MemorySession;
        import java.lang.foreign.SymbolLookup;
        import java.lang.foreign.ValueLayout;
        import java.lang.invoke.MethodHandles;
        import java.lang.invoke.MethodType;

        import static java.lang.foreign.SegmentAllocator.implicitAllocator;

        public class JavaClass {

          static {
            System.loadLibrary("ffm");
          }

          public static Addressable getMessage() {
            return implicitAllocator().allocateUtf8String("Hello World!").address();
          }

          public static void main(String... args) {
            try {
              var linker = Linker.nativeLinker();
              var symbolLookup = SymbolLookup.loaderLookup();
              var symbol = symbolLookup.lookup("nativeMethod").orElseThrow();
              var functionDesc = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS);
              var methodHandle = linker.downcallHandle(symbol, functionDesc);
              var upcallMethodType = MethodType.methodType(Addressable.class);
              var upcallFunctionDesc = FunctionDescriptor.of(ValueLayout.ADDRESS);
              var upcallMethodHandle = MethodHandles.lookup().findStatic(JavaClass.class, "getMessage", upcallMethodType);
              var upcallSymbol = linker.upcallStub(upcallMethodHandle, upcallFunctionDesc, MemorySession.openImplicit());
              methodHandle.invoke(upcallSymbol);
            } catch (Throwable e) {
              System.out.println(e);
            }
          }
        }

              alanb Alan Bateman
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              11 Start watching this issue

                Created:
                Updated:
                Resolved: