Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can JVMTI agent set a JVM flag on startup?

Tags:

java

jvm

jvmti

In order to support better profiling data I would like my JVMTI agent to enable a couple of JVM flags. The agent in question is Honest-Profiler and it is can only be loaded at startup.

I would like to enable the flags: -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints

As per issue documented here if the flags are not on we get a biased profile. It would be good to go beyond warning the user and just enable the flag.

like image 518
Nitsan Wakart Avatar asked May 18 '16 11:05

Nitsan Wakart


2 Answers

As to DebugNonSafepoints you don't even need to set this flag. Look at debugInfoRec.cpp:

static inline bool compute_recording_non_safepoints() {
  if (JvmtiExport::should_post_compiled_method_load()
      && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
    // The default value of this flag is taken to be true,
    // if JVMTI is looking at nmethod codes.
    // We anticipate that JVMTI may wish to participate in profiling.
    return true;
  }

  // If the flag is set manually, use it, whether true or false.
  // Otherwise, if JVMTI is not in the picture, use the default setting.
  // (This is true in debug, just for the exercise, false in product mode.)
  return DebugNonSafepoints;
}

If the flag is not set, debug info is still recorded when JVMTI CompiledMethodLoad notifications are enabled. You just need to request can_generate_compiled_method_load_events capability and turn on JVMTI_EVENT_COMPILED_METHOD_LOAD notifications.

That's exactly how I handle it in my async-profiler project.


There is no safe way to change unmanageable JVM flags in run-time. However, there is an ugly hack to do this on Linux.

  1. Read /proc/self/maps to find the base address of libjvm.so.
  2. Use ELF format reader to discover an offset of the desired symbol in the dynamic library.
  3. Write directly to the address of this symbol.

Here is a sample code for this trick.

like image 178
apangin Avatar answered Sep 30 '22 13:09

apangin


There are a couple of JVM flags which can be written at runtime using com.sun.management.HotSpotDiagnosticMXBean.setVMOption.

(For a list see http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/b92c45f2bc75/src/share/vm/runtime/globals.hpp and search for manageable).

Unfortunately for your use case the option UnlockDiagnosticVMOptions is not writable.

like image 39
wero Avatar answered Sep 30 '22 12:09

wero