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

Popping a frame when doing a OnClassPrepare can provoke non initialization

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 11
    • hotspot

      Consider the following class:

      class Foo {
        public static final boolean CLINIT_RUN;
        static {
          System.err.println("Here we are!");
          CLINIT_RUN = true;
        }
      }

      As soon as the class would be used, it should have CLINIT_RUN to true such as:

      class Test implements Runnable {
        // This is the frame that will get PopFrame'd and it should re-execute.
        public void loadAndRun() {
          System.err.println("Start Load And Run");
          System.err.println("CLINIT_RUN " + Foo.CLINIT_RUN);
        }

        @Override
        public void run() {
          loadAndRun();
        }
      }

      Now consider a main such as:

      public class Main {
        public static native void popFrame(Thread t);

        public static void main(String[] args) throws Exception {
          System.err.println("Starting main, going to start the target thread\n");
          Thread t = new Thread(new Test());
          t.start();

          // Wait a second, enough for the Test thread to suspend itself.
          Thread.sleep(1000);

          // Uncomment this line and there is a bug.
          // popFrame(t);

          Thread.sleep(3000);
          t.resume();
          t.join();

          System.err.println("Foo.CLINIT_RUN " + Foo.CLINIT_RUN);
        }
      }

      Expected behavior is:
      $ java Main
      Starting main, going to start the target thread

      Start Load And Run
      Here we are!
      CLINIT_RUN true
      Foo.CLINIT_RUN true

      But adding an agent that:
         - Suspends the thread during class prepare
         - And then pops the frame
         - At resume, the class is no longer initialized

      $ java -agentpath:/tmp/class_prepare/testagent.so Main

      Starting main, going to start the target thread

      Start Load And Run
      Preparing class LFoo; and suspending 0
      Suspended
      Popping a thread 0
      CLINIT_RUN false
      Foo.CLINIT_RUN false

      (Notice the false in the print-outs)

      When talking with Serguei, I believe this is a duplicate of another issue he was talking about but I have the reproducer so thought it could help.

        1. Main.java
          1.0 kB
        2. testagent.cc
          2 kB

            Unassigned Unassigned
            jcbeyler Jean Christophe Beyler
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: