2

I would like to enable debugging at some point on the current JVM without adding the command line parameters -agentlib:jdwp.

Is it possible to do so programmatically from within the current running JVM ? Without any third party libraries ?

Other command line parameters (such as -Djdk.attach.allowAttachSelf=true) can be considered.

VirtualMachine vm = VirtualMachine.attach(Long.toString(ProcessHandle.current().pid()));
vm.loadAgentLibrary("jdwp", "transport=dt_socket,server=y,address=8000,suspend=n");

causes :

com.sun.tools.attach.AgentLoadException: Failed to load agent library: _Agent_OnAttach@12 is not available in jdwp
Simon
  • 2,353
  • 1
  • 13
  • 28
  • 3
    Basically, you answered it yourself. The jdwp agent doesn’t support `OnAttach`, most likely because it requires capabilities that can only be activated in `OnLoad`. – Holger Apr 30 '21 at 14:08
  • Indeed, but is it because of a technicality or just a design principle ? There might be some workarounds or (un)known alternatives – Simon Apr 30 '21 at 16:09
  • 2
    It’s not hard to imagine that activating certain capabilities, especially those needed by a debugger, may require selecting alternative implementations of certain JVM features, with an impact on performance, so the JVM configures itself at initialization according to the requested capabilities and can’t change afterwards. Just like you can’t change the garbage collector algorithm after startup. – Holger Apr 30 '21 at 16:19
  • It does have an impact, I agree. Though you can attach a profiler/agent that can intercept, inspect and rewrite classes at runtime. I dont know how the debugger capability is designed nor implemented but overriding a class with a lock at the breakpoint could do it I (naively) suppose. Answer seems to be "no" (as per attempt first of all), I just wish I had a technical reason why. – Simon May 03 '21 at 10:04
  • 1
    Setting a break point could be emulated by hot-swapping the code to something that stops the execution at that point, but the hot-swapping itself has its own limitations. Already running code may continue with the old code and the swapping may in general have a significant delay before becoming effective. So it’s nowhere like the “suspend thread” action and it may miss a lot of executions before truly stopping. And it still doesn’t imply inspecting or changing local variables. You may inject even more code for that, but it won’t work, e.g. to inspect a hanging thread. – Holger May 03 '21 at 11:06

1 Answers1

3

In modern JVM (Java 6+) the agents use the JVM TI interface.

The JVM Tool Interface (JVM TI) is a programming interface used by development and monitoring tools. It provides both a way to inspect the state and to control the execution of applications running in the Java virtual machine (VM).

Inside JVM TI, you must enable the desired capabilities

The capabilities functions allow you to change the functionality available to JVM TI--that is, which JVM TI functions can be called, what events can be generated, and what functionality these events and functions can provide.

Which capabilities can be added when (which state of the JVM) is vendor-dependent. JDWP is just the protocol for debugging between the JVM and the debugger. It simply leverages the capabilities of the JVM TI just like any other agent. Meanwhile, most-probably, the capabilities for debugging can only be added in the OnLoad phase (in most JVM). (I.e: can_generate_breakpoint_events, can_suspend, ...)

Add Capabilities: Typically this function is used in the OnLoad function. Some virtual machines may allow a limited set of capabilities to be added in the live phase.

This explains why the jdwp agent must be declared on JVM startup in order to add the proper capabilities to JVM TI.

Doc: https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html#capability

Credits to @Holger for pointing the direction.

Simon
  • 2,353
  • 1
  • 13
  • 28
  • See https://github.com/openjdk/jdk/blob/master/src/hotspot/share/prims/jvmtiManageCapabilities.cpp for a list of which capabilities are only available on JVM startup, in HotSpot. – comp500 Oct 03 '21 at 18:41