Skip to content
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

Add support for JCMD and the Attach API #8915

Open
roberttoyonaga opened this issue May 13, 2024 · 6 comments
Open

Add support for JCMD and the Attach API #8915

roberttoyonaga opened this issue May 13, 2024 · 6 comments

Comments

@roberttoyonaga
Copy link
Collaborator

roberttoyonaga commented May 13, 2024

TL;DR

Support executing commands issued fromjcmd and support connection to SubstrateVM through the Attach API.

Motiviation

Native Image currently doesn't support jcmd. Currently, we work around this by relying on catching and handling Linux signals for many things. Examples include, generating heap dumps, dumping threads, generating NMT reports. JFR also cannot dynamically be controlled at runtime (unless JMX is used). Signals are not ideal because there are a limited number of usable signals. They are also not ideal because arguments cannot be specified. jcmd would solve these problems because it would allow for an unlimited number of commands and also allows for arguments.

Implementing the Attach API also opens the door to the possibility of other Java tools like jmap, jstack, etc being supported in the future.

Goals

Describe the solution you'd like.

  • Implement the Attach API in SubstrateVM
  • Lay groundwork for issuing commands via jcmd. Focus on NMT, heap dumps, and JFR commands for now.

Non-Goals

  • Support Java agents using dynamic attach.
  • Support jmap, jstack, or other tools that use the Attach API
  • Support all jcmd commands. The goal is to put the piping in place and support a few commands to start with.
@roberttoyonaga
Copy link
Collaborator Author

roberttoyonaga commented May 13, 2024

I'm weighing the benefits of implementing this as uninterruptible vs interruptible. The implementation in OpenJDK is in native code: " The rationale for a pure native implementation is to be able to execute diagnostic commands even in critical situations like an out-of-memory condition. "

However, implementing this interruptibly would lower complexity by allowing for using java.nio.channels.SocketChannel to handle unix domain sockets and jdk.internal.misc.Signal for handling SIGQUIT (which kicks off the Attach API handshake).

Currently, handling signals for dumping thread stacks, or head dumps is interruptible. I am leaning toward implementing the Attach API and JCMD support interruptibly in Java. Are there any concerns about this?

@fniephaus
Copy link
Member

I can help out with this.

Excellent, looking forward to your contribution, Robert! :)

Currently, handling signals for dumping thread stacks, or head dumps is interruptible. I am leaning toward implementing the Attach API and JCMD support interruptibly in Java. Are there any concerns about this?

Maybe @christianhaeubl has an opinion on this?

@christianhaeubl
Copy link
Member

The implementation in OpenJDK is in native code.

If OpenJDK implements a feature fully in native code, it is pretty likely that we will need uninterruptible code (at least in the long run - we got bitten by that a couple times in the past). When implementing a prototype, it is definitely easier to use interruptible code though. Maybe, you can roughly sketch the steps that the attach API needs to execute, then it is easier to estimate if we have a reasonable chance with interruptible code.

@roberttoyonaga
Copy link
Collaborator Author

roberttoyonaga commented May 14, 2024

I was able to make a rough working prototype in interruptible Java using the high-level JDK features for handling sockets and signals. The general flow is:

  • Catch SIGQUIT issued by the client trying to connect
  • Search for an ".attach_pid" file and recognize an attempt at a connection handshake is in progress.
  • Open a server unix domain socket and accept data from the client.
  • Parse commands and take actions.

So far, it doesn't seem like there are issues implementing it interruptably, especially since we already handle initiating dumping heap/threads interruptably. The actions to perform that we receive through jcmd can be uninterruptible, while the Attach API code itself is interruptible. However, it would mean we can't use jcmd in situations like OOM.

I could try and implement it uninterruptably to future proof it. In that case, I would copy how we handle SIGPROF, and try to use native code to handle the sockets.

@christianhaeubl
Copy link
Member

christianhaeubl commented May 15, 2024

Thanks!
I guess the middle ground is to implement the infrastructure with interruptible code for now (that is probably much easier than using uninterruptible code). However, for the actual commands, we should enforce that they use uninterruptible code. If we ever run into issues, then we would only need to rewrite the infrastructure but not the individual commands.

@roberttoyonaga
Copy link
Collaborator Author

Ok, I think that's a good plan. I'll start with that. Thanks Christian!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo
Development

No branches or pull requests

3 participants