How can JVMTI agent set a JVM flag on startup?
Asked Answered
A

3

7

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.

Alanalana answered 18/5, 2016 at 11:59 Comment(1)
If you will not found legal solution, there is gory approach from @apangin: github.com/odnoklassniki/one-elf/blob/master/test/one/jvm/… it founds address of loaded libjvm.so and calculates flag address from .so address + .symtab constant offset (but it not always works, depends on concrete flag usage in VM code)Olivarez
Y
11

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.

Yellowthroat answered 18/5, 2016 at 17:23 Comment(5)
I had managed it via Helfy (and also with Hotspot SA). I will show it with sample code when I have prepared itPowerhouse
here it is github.com/serkan-ozal/jvm-playground/blob/master/src/main/java/…Powerhouse
@SerkanÖzal Cool! Didn't think Helfy could be used for that. Would you mind adding this example to Helfy repo on github?Yellowthroat
sure @apangin, if you want I can send a PR :)Powerhouse
@SerkanÖzal Sure, go ahead and create PR. Thank you!Yellowthroat
B
1

Ok, this is not a precise answer but more of a nudge in certain direction ....

In services/writeableFlags.hpp there are static methods for setting VM flags. The success will depend on whether these flags are actually mutable but it would be the good place to start poking around. I haven't tried calling these methods from JVMTI agent but, theoretically, it should work.

Barrie answered 18/5, 2016 at 12:23 Comment(0)
B
1

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.

Brookins answered 18/5, 2016 at 12:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.