Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

detect the end of the bootstrapping phase of the JVM

Tags:

java

jvm

Is there a way to detect the end of the bootstrapping phase of the JVM?

edit::

so to provide a bit more context, what i am trying to do is to instrument the JDK. And this is a full blown instrumentation that records every LOAD, STORE, INVOKE byte code instruction. As the instructions are executed their data is sent to a static method, that is loaded from the xbootclasspath. This static method captures all this information and stores all of this as a trace for performing analysis at a later time.

Now, when i do this for the JDK, i do not want to disturb the way classes are loaded in the JVM, which might result in a program crash. I was guessing that the best way to go about it is to detect the point in time when the JVM is done bootstrapping, so that I can safely turn on my instrumentation thereafter. (I plan to not instrument any of the code, while the bootstrapping is taking place.) Is this even the right way to go about it?

like image 407
vijay Avatar asked Nov 03 '22 21:11

vijay


1 Answers

In addition to my previous comment about looking into FERRARI and MAJOR I want to say several things:

  • Both tools are only available for download as compiled Java JAR archives.
  • So I wrote to the scientists who have created those tools today and asked them our question. As soon as I will receive an answer I will report back here.
  • Anyway, I have looked into FERRARI's architecture and think I may have found out how they do it.

So here is my educated guess (still untested) about what you could do:

  • Instrument your JDK classes.
  • Add one simple class BootstrapLock as described below.
  • Re-pack the instrumented + the new class into a modified rt.jar.
  • Write a little dummy Java agent as described below.
public class BootstrapLock {
    private static volatile boolean inBootstrap = true;

    public static boolean inBootstrap() {
        return inBootstrap;
    }

    public static synchronized void setEndOfBS() {
        inBootstrap = false;
    }
}

public class DummyAgent {
    public static void premain(String options, Instrumentation ins) {
        BootstrapLock.setEndOfBS();
    }
}

So basically the logic is as follows:

  • Agents are loaded before the main application class, but after bootstrapping.
  • Thus the very fact that the agent is active means that bootstrapping is finished.
  • Thus the agent can switch off the global marker inBootstrap.
  • Your instrumented classes can check the marker in order to determine if their additional instrumentation code should be bypassed or not.

I am unsure if I have enough time to test this anytime soon, but at least I wanted to post this answer here so maybe you, Vijai, can also look into it and provide some feedback. Four eyes see more than two...


Update: One of the FERRARI authors has answered my inquiry and confirmed my explanation above. You can just use a java agent as a marker of JVM having finished its bootstrapping. Maybe you do not even need the additional class, but just check if the agent has been loaded into the JVM yet. It would make things even simpler, I just do not know if it performs well. Just test it.

like image 189
kriegaex Avatar answered Nov 08 '22 09:11

kriegaex