Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public static PosixAttachApiSupport singleton() {
}

@Override
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/os/posix/attachListener_posix.cpp#L474-L490")
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/posix/attachListener_posix.cpp#L344-L360")
public void startup() {
String path = getSocketFilePath();
try (CCharPointerHolder f = CTypeConversion.toCString(path)) {
Expand All @@ -76,7 +76,7 @@ public void startup() {
}

@Override
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/os/posix/attachListener_posix.cpp#L537-L568")
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/posix/attachListener_posix.cpp#L409-L440")
public boolean isInitTrigger() {
String filename = ".attach_pid" + ProcessHandle.current().pid();
if (isInitTrigger0(filename)) {
Expand All @@ -94,7 +94,7 @@ private static boolean isInitTrigger0(String path) {
}

@Override
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/os/posix/attachListener_posix.cpp#L501-L523")
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/posix/attachListener_posix.cpp#L373-L395")
public void initialize() {
lock.lock();
try {
Expand Down Expand Up @@ -130,7 +130,7 @@ private boolean isSocketFileValid() {
}

@Override
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/os/posix/attachListener_posix.cpp#L170-L181")
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/posix/attachListener_posix.cpp#L169-L180")
public void shutdown(boolean inTeardownHook) {
if (!shutdownRequested.compareAndSet(false, true) && Thread.currentThread() instanceof AttachListenerThread) {
/*
Expand Down Expand Up @@ -186,7 +186,7 @@ private String getSocketFilePath() {
return cachedSocketFilePath;
}

@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/os/posix/attachListener_posix.cpp#L186-L250")
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/posix/attachListener_posix.cpp#L185-L249")
private boolean createListener() {
assert lock.isHeldByCurrentThread();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,163 +26,69 @@

package com.oracle.svm.core.posix.attach;

import java.nio.charset.StandardCharsets;

import jdk.graal.compiler.word.Word;
import org.graalvm.nativeimage.StackValue;
import org.graalvm.nativeimage.c.type.CCharPointer;
import org.graalvm.nativeimage.c.type.CTypeConversion;
import org.graalvm.word.Pointer;
import org.graalvm.word.PointerBase;

import com.oracle.svm.core.attach.AttachListenerThread;
import com.oracle.svm.core.posix.PosixUtils;
import com.oracle.svm.core.posix.headers.Unistd;
import com.oracle.svm.core.util.BasedOnJDKFile;

public final class PosixAttachListenerThread extends AttachListenerThread {
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/aix/attachListener_aix.cpp#L82") //
private static final String PROTOCOL_VERSION = "1";
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/aix/attachListener_aix.cpp#L269") //
private static final int VERSION_SIZE = 8;
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/aix/attachListener_aix.cpp#L85") //
private static final int ATTACH_ERROR_BAD_VERSION = 101;

/**
* Each attach request consists of a fixed number of zero-terminated UTF-8 strings.
* {@code <version><commandName><arg0><arg1><arg2>}
*/
private static final int EXPECTED_STRING_COUNT = 2 + ARG_COUNT_MAX;
private static final int MAX_REQUEST_LEN = (VERSION_SIZE + 1) + (NAME_LENGTH_MAX + 1) + (ARG_COUNT_MAX * (ARG_LENGTH_MAX + 1));

private final int listener;

public PosixAttachListenerThread(int listener) {
this.listener = listener;
}

@Override
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+3/src/hotspot/os/posix/attachListener_posix.cpp#L254-L311")
protected PosixAttachOperation dequeue() {
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/posix/attachListener_posix.cpp#L256-L313")
protected AttachOperation dequeue() {
while (true) {
int socket = AttachHelper.waitForRequest(listener);
if (socket == -1) {
return null;
}

PosixAttachOperation op = readRequest(socket);
PosixAttachSocketChannel channel = new PosixAttachSocketChannel(socket);
AttachOperation op = readRequest(channel);
if (op == null) {
/* Close the socket and try again. */
Unistd.NoTransitions.close(socket);
channel.close();
} else {
return op;
}
}
}

/** This method reads and processes a single request from the socket. */
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/aix/attachListener_aix.cpp#L268-L359")
private static PosixAttachOperation readRequest(int socket) {
int strCount = 0;
int[] stringEnds = new int[EXPECTED_STRING_COUNT];
Pointer buf = StackValue.get(MAX_REQUEST_LEN);

/* Read until all expected strings have been read, the buffer is full, or EOF. */
int offset = 0;
do {
int n = PosixUtils.readUninterruptibly(socket, buf, MAX_REQUEST_LEN, offset);
if (n == -1) {
return null;
} else if (n == 0) {
break;
}

int end = offset + n;
while (offset < end) {
if (buf.readByte(offset) == 0) {
/* End-of-string found. */
stringEnds[strCount] = offset;
strCount++;
}
offset++;
}
} while (offset < MAX_REQUEST_LEN && strCount < EXPECTED_STRING_COUNT);

if (strCount != EXPECTED_STRING_COUNT) {
/* Incomplete or invalid request. */
return null;
}

String version = decodeString(buf, stringEnds, 0);
if (!PROTOCOL_VERSION.equals(version)) {
complete(socket, ATTACH_ERROR_BAD_VERSION, null);
return null;
}

String name = decodeString(buf, stringEnds, 1);
if (name.length() > NAME_LENGTH_MAX) {
return null;
}

String arg0 = decodeString(buf, stringEnds, 2);
if (arg0.length() > ARG_LENGTH_MAX) {
return null;
}
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/posix/attachListener_posix.cpp#L102-L139")
private static class PosixAttachSocketChannel extends AttachSocketChannel {
private int socket;

String arg1 = decodeString(buf, stringEnds, 3);
if (arg1.length() > ARG_LENGTH_MAX) {
return null;
PosixAttachSocketChannel(int socket) {
this.socket = socket;
}

String arg2 = decodeString(buf, stringEnds, 4);
if (arg2.length() > ARG_LENGTH_MAX) {
return null;
@Override
public int read(PointerBase buffer, int size) {
return PosixUtils.readUninterruptibly(socket, (Pointer) buffer, size, 0);
}

return new PosixAttachOperation(name, arg0, arg1, arg2, socket);
}

private static String decodeString(Pointer buf, int[] stringEnds, int index) {
int start = index == 0 ? 0 : stringEnds[index - 1] + 1;
int length = stringEnds[index] - start;
assert length >= 0;
return CTypeConversion.toJavaString((CCharPointer) buf.add(start), Word.unsigned(length), StandardCharsets.UTF_8);
}

@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+15/src/hotspot/os/posix/attachListener_posix.cpp#L323-L325")
private static void complete(int socket, int code, String response) {
/* Send the return code. */
byte[] returnCodeData = Integer.toString(code).getBytes(StandardCharsets.UTF_8);
sendData(socket, returnCodeData);

byte[] lineBreak = System.lineSeparator().getBytes(StandardCharsets.UTF_8);
sendData(socket, lineBreak);

/* Send the actual response message. */
if (response != null && !response.isEmpty()) {
byte[] responseBytes = response.getBytes(StandardCharsets.UTF_8);
sendData(socket, responseBytes);
sendData(socket, lineBreak);
@Override
protected void write(byte[] data) {
PosixUtils.writeUninterruptibly(socket, data);
}

AttachHelper.shutdownSocket(socket);
Unistd.NoTransitions.close(socket);
}

private static void sendData(int socket, byte[] data) {
PosixUtils.writeUninterruptibly(socket, data);
}

private static class PosixAttachOperation extends AttachOperation {
private final int socket;

PosixAttachOperation(String name, String arg0, String arg1, String arg2, int socket) {
super(name, arg0, arg1, arg2);
this.socket = socket;
protected boolean isOpen() {
return socket != -1;
}

@Override
public void complete(int code, String response) {
PosixAttachListenerThread.complete(socket, code, response);
public void close() {
if (isOpen()) {
AttachHelper.shutdownSocket(socket);
Unistd.NoTransitions.close(socket);
socket = -1;
}
}
}
}
Loading
Loading