-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GR-56601] Add support for JCMD and the Attach API #9232
base: master
Are you sure you want to change the base?
Conversation
d980e19
to
4893c32
Compare
4893c32
to
db5a559
Compare
The GHA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR, I started reviewing and integrating it so please don't push any further changes for now.
package com.oracle.svm.core.dcmd; | ||
|
||
/** For validation of input arguments. */ | ||
public class DcmdParseException extends Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this exception really needed? As far as I can see, HotSpot often just throws an IllegalArgumentException
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I agree, IllegalArgumentException
is probably good enough here
import com.oracle.svm.core.thread.ThreadDumpToFileDcmd; | ||
|
||
@AutomaticallyRegisteredFeature | ||
public class DcmdFeature implements InternalFeature { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can diagnostic commands also be triggered via some other way than the Attach API? If not, then I will merge the attach
and dcmd
packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In OpenJDK, diagnostic commands can also be used through JMX (DiagnosticCommandMBean
). I think they can also be used directly from within the JVM. I'm not planning to implement DiagnosticCommandMBean
any time soon. And I don't really see too much value in using DCMD directly from within SVM. So it's probably fine to merge attach
and dcmd
packages.
import static java.util.concurrent.TimeUnit.MINUTES; | ||
import static java.util.concurrent.TimeUnit.SECONDS; | ||
|
||
public class JfrDumpDcmd extends AbstractDcmd { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't we use jdk.jfr.internal.dcmd.DCmdDump
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could. But jdk.jfr.internal.dcmd.DCmdDump
expects to be provided with a jdk.jfr.internal.dcmd.ArgumentParser
and also writes back results differently (reportOperationComplete
). In OpenJDK, each individual DCMD is responsible for sending back their own specific responses. In this PR, only the AttachListener classes know about the sockets and the DCMDs just return a simple string for the AttachListener to deal with.
Summary
This pull request adds initial support for the Attach-API and JCMD. Specifically, other processes may now use the "attach" mechanism to communicate with Native Images using JCMD. This has been implemented as an optional feature that is excluded from the image by default (similar to JFR or heap dumping).
For now the following JCMD command types are supported:
Support for more commands should be straightforward to add in the future.
Related issue: #8915
Motivation
Native Image has a growing number of features such as NMT, heap dumps, thread dumps, and compilation dumps that rely on handling Unix signals to perform operations requested at runtime. This is not ideal because there is a limited number of Unix signals that are available to be used. It is also not ideal because arguments cannot be easily used with signals. Supporting JCMD would be a better alternative to signals because we can support an unlimited number of commands and also accept arguments.
JFR in OpenJDK heavily uses JCMD to accept user requests at runtime. Currently, there is no way to stop/start/dump recordings spontaneously at runtime (apart from using the remote JMX feature - which has significant overhead with respect to image size). This is inconvenient if a user wants to diagnose a problem without shutting down or restarting their application. For example, if a user wants to access JFR recordings from their application, they need to terminate their application so that a JFR dump is created. With JCMD they are able to dump recordings whenever they desire without needing to restart their entire application.
Usage
Build this PR with
mx build
Build your executable with the
attach
monitoring option. This will automatically include JCMD as well. Make sure your application runs long enough for you to enter some requests through JCMD.mx native-image --enable-monitoring=nmt,jfr,jvmstat,threaddump,attach YourApp
Run your app. Then find its PID.
./yourapp
In another terminal:
$JAVA_HOME/bin/jcmd <your app's PID> help
$JAVA_HOME/bin/jcmd <your app's PID> help JFR.stop
$JAVA_HOME/bin/jcmd <your app's PID> help help
$JAVA_HOME/bin/jcmd <your app's PID> VM.native_memory summary
Limitations
Attach-API only works on posix so far. This is not a regression since headp dump, thread dump, compilation dump, nmt dump, and JFR, all don't work on Windows anyway (since they require unix signals to operate).
The Windows implementation will be largely independent of code in this posix implementation. So there will be no need to go back and rework anything here. It would just be additional.
Other notes