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

JVM hangs on pinned virtual threads if a ClassFileTransformer was registered

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 21.0.2
    • core-libs
    • generic
    • generic
    • Verified

      A DESCRIPTION OF THE PROBLEM :
      When running an application with pinned, blocked virtual threads AND an active javaagent, the application hangs. The issues was originally reported for the opentelemetry autoinstrumentation javaagent here: https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/10181

      The issue can be forced to occur when starting the JVM with the `-Djdk.tracePinnedThreads=short` flag.
      With the flag added, the JVM will hang immediately when a pinned virtual thread blocks (e.g. Thread.sleep).
      Without the flag according to the original report on the opentelemetry-agent the application will eventually also hang, but it is harder to reproduce.

      The hanging JVM is unresponsive, making this issue a bit hard to debug: An attached debugger won't be able to pause the JVM, the JVM will not respond to `jcmd` commands and `jfr` won't flush it's output in time to help with analysis.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Build a javaagent which just registeres an empty ClassFileTransformer

      2. Run the provided sample Java application with `-Djdk.tracePinnedThreads=short` and the `-javaagent:` built from step 1 :

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The JVM terminates normally after printing "Done sleep"
      ACTUAL -
      The JVM hangs after printing "Entering sleep"

      ---------- BEGIN SOURCE ----------
      Agent-Premain class:
      ```
      import java.lang.instrument.ClassFileTransformer;
      import java.lang.instrument.IllegalClassFormatException;
      import java.lang.instrument.Instrumentation;
      import java.security.ProtectionDomain;

      public class AgentMain {
          public static void premain(String agentArgs, Instrumentation inst) {
              System.out.println("Registering No-Op transformer");
              inst.addTransformer(new ClassFileTransformer() {
                  @Override
                  public byte[] transform(Module module, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
                      return null;
                  }
              });
          }
      }
      ```

      Application Main Class:

      ```
      import java.util.concurrent.Executors;

      public class Main {

          public static void main(String[] args) {
              try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
                  Object lock = new Object();
                  executor.submit(() -> {
                      synchronized (lock) {
                          try {
                              System.out.println("Entering sleep");
                              Thread.sleep(100);
                              System.out.println("Done sleep ");
                          } catch (InterruptedException e) {
                              throw new RuntimeException(e);
                          }
                      }
                  });
              }
          }
      }
      ```

      ---------- END SOURCE ----------

      FREQUENCY : always


            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: