note that for *nix systems that use SIGQUIT as an initiator for attach,
there exists a potential fatal "bug" where (especially a programmatic)
attach attempt may send SIGQUIT before the target/attachee JVM has
initialized such that its signal handlers
are installed.
If the target JVM has not initialized its sig handlers when SIGQUIT is
received the default action will occur, which is to terminate
the process.
on Linux, this is avoided by a "busy wait" polling the sigmasks of the
target processes 'stat' file (in /proc) the only way to obtain
this info on MacOS is to use sysctl as mentioned in (4) below.
I would avoid using jextract to model the kernel structures and simply
call the existing native API (via FFM instead of JNI as it is today) to
read the sigmasks - there is no need to go directly to sysctl & kernel
data structures.
I would certainly *not* remove this as it will cause an (actual)
regression in behaviors.
As to Windows, it operates differently to *nix, I believe (but I could
be wrong) due to differences in O.S relating to asynch inter-
process signalling and UDS behavior
Rgds
- Larry
On 6/24/25 7:30 AM, Philippe Marschall wrote:
Hello
Since the audience has been expanded let me summarize what would be
needed to make jdk.attach free of JNI on Unix (AIX, Linux, macOS).
jdk.attach currently uses JNI for four different things.
1. reading and writing unix domain sockets
2. accessing uid, guid and permissions of a file
3. sending SIGQUIT to an arbitrary PID, including self in the case of
self attach
4. sysctl({CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}) on macOS
For 1. and 2. there are already supported Java based APIs and I have
patches in case somebody is willing to sponsor this work / open a JIRA.
3. kill(SIGQUIT)
This can be done quite easily using FFM as the signature of kill() is
quite simple. The signature and values are the same an Linux and macOS
and I assume AIX as well, but I don't have access to a machine to
verify. Overlap with existing code is with ProcessHandleImpl.destroy0
which sends SIGKILL or SIGTERM to a PID but performs additional
checks. So an API to send a signal to a PID would be needed. It is my
understanding that jdk.internal.misc.Signal only supports sending
signal to self.
4. sysctl({CTL_KERN, KERN_PROC, KERN_PROC_PID, pid})
This is more complicated as the kinfo_proc and extern_proc structs are
quite large. jextract is the easiest way to come up with the
definitions. However the amount of generated code is quite large even
after filtering. The generated code can be further cut down using
manual editing. I have not yet looked into replacing not needed struct
fields with padding. To the best of my knowledge jextract hasn't the
been included into the JDK build.
Overlap here is in ProcessHandleImpl_macosx.c with the functions
os_getParentPidAndTimings and getUID but they access different fields
of extern_proc.
Honestly here I'm not sure why this check is needed at all. The
reasoning given for the check in VirtualMachineImpl.c would in my
option apply to Linux and AIX as well but this check is not performed
there. Removing this check from the macOS implementation would
obviously be the easiest.
I can't speak for Windows as I'm not familiar enough with Windows APIs.
Cheers
Philippe
On 19.06.25 14:40, Magnus Ihse Bursie wrote:
Hi Philippe,
There is an ongoing effort about "Panamization" (that is, adapting it
to use FFM instead of JNI) of native code in the JDK in general. This
is discussed on the core-libs-dev mailing list. I've cc:ed them. I
think it would be beneficial if you coordinate your efforts with the
Panamization effort.
/Magnus
On 2025-06-15 17:43, Philippe Marschall wrote:
Hello
I further pursued the approach
- Rebased the Linux implementation [1], implemented the permission
check using JSR 203 and the Unix domain sockets using JEP 380.
- Applied the same changes to the AIX implementation [2].
- Switched Linux to an FFM based kill implementation [3], completely
getting rid of JNI.
- Updated the macOS implementation [4], implemented the permission
check using JSR 203 and the Unix domain sockets using JEP 380.
- Switched macOS to an FFM based kill and sysctl implementation [5],
completely getting rid of JNI.
I ran the serviceability test suite on Linux and macOS and it
passes. I manually verified that I can attach to JVMs using local
builds.
I could not test on AIX.
[1] https://github.com/marschall/jdk/
commit/3a7796daadad7c9d2d85e9e4623f170baecc0e41
[2] https://github.com/marschall/jdk/
commit/962729e0bfb6b7d86af303f25c6670d407d1d2d9
[3] https://github.com/marschall/jdk/
commit/7b5f1bf6f55458a7f69f50b8fdf4986e22202559
[4] https://github.com/marschall/jdk/
commit/93372a124eca6078fde5597c2498b381a4ef5dfa
[5] https://github.com/marschall/jdk/commit/
c5faf9655bbb85cc3ed9b2a7ef15b08ab83d1d8b
Cheers
Philippe
On 20.04.22 22:13, Philippe Marschall wrote:
Hello
I hope this is the right mailing list. I recently had a look at the
Linux attach provider implementation and could not help but noticing
that a large part, if not all of it, could be replaced with Java.
Besides getting rid of the C code this should allow us to unify the
AIX,
Linux and macOS implementations under a single Unix implementation.
The permission check can be implemented using JSR 203 [1] to access
uid,
gid and file mode and using jdk.internal.misc.VM to get the euid
and egid.
Reading and writing to Unix domain sockets can be done through JEP
380 [2].
Sending SIGQUIT to a process could in theory done through JEP 102 [3]
however sending SIGQUIT to self is currently blocked. This is required
for the self attach mechanism. There a very small C function is still
needed for now, this is hopefully portable.
I did a small prototype [4]. The tier1 suite runs and I can attach
to a
local JVM.
The overhead will likely be a bit higher as we go through more JDK
abstractions.
[1] https://jcp.org/en/jsr/detail?id=203
[2] https://openjdk.java.net/jeps/380
[3] https://openjdk.java.net/jeps/102
[4]
https://github.com/marschall/jdk/
commit/207dac7e4d1bd65450bbd2c9e14d33fc34b7cebc
Cheers
Philippe