8344671: Few JFR streaming tests fail with application not alive error on MacOS 15

Reviewed-by: dholmes, kevinw
This commit is contained in:
Larry Cable
2025-04-02 16:00:14 +00:00
committed by Kevin Walls
parent 49cb7aaad9
commit d979bd8592
3 changed files with 57 additions and 16 deletions

View File

@@ -72,13 +72,15 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
if (!socket_file.exists()) {
File f = createAttachFile(pid);
try {
sendQuitTo(pid);
checkCatchesAndSendQuitTo(pid, false);
// give the target VM time to start the attach mechanism
final int delay_step = 100;
final long timeout = attachTimeout();
long time_spend = 0;
long time_spent = 0;
long delay = 0;
boolean timedout = false;
do {
// Increase timeout on each attempt to reduce polling
delay += delay_step;
@@ -86,18 +88,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
Thread.sleep(delay);
} catch (InterruptedException x) { }
time_spend += delay;
if (time_spend > timeout/2 && !socket_file.exists()) {
timedout = (time_spent += delay) > timeout;
if (time_spent > timeout/2 && !socket_file.exists()) {
// Send QUIT again to give target VM the last chance to react
sendQuitTo(pid);
checkCatchesAndSendQuitTo(pid, !timedout);
}
} while (time_spend <= timeout && !socket_file.exists());
} while (!timedout && !socket_file.exists());
if (!socket_file.exists()) {
throw new AttachNotSupportedException(
String.format("Unable to open socket file %s: " +
"target process %d doesn't respond within %dms " +
"or HotSpot VM not loaded", socket_path,
pid, time_spend));
pid, time_spent));
}
} finally {
f.delete();
@@ -216,7 +219,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
//-- native methods
static native void sendQuitTo(int pid) throws IOException;
static native boolean checkCatchesAndSendQuitTo(int pid, boolean throwIfNotReady) throws IOException, AttachNotSupportedException;
static native void checkPermissions(String path) throws IOException;

View File

@@ -28,11 +28,13 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syslimits.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/un.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -110,15 +112,54 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_connect
/*
* Class: sun_tools_attach_VirtualMachineImpl
* Method: sendQuitTo
* Method: checkCatchesAndSendQuitTo
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_sendQuitTo
(JNIEnv *env, jclass cls, jint pid)
JNIEXPORT jboolean JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkCatchesAndSendQuitTo
(JNIEnv *env, jclass cls, jint pid, jboolean throwIfNotReady)
{
if (kill((pid_t)pid, SIGQUIT)) {
JNU_ThrowIOExceptionWithLastError(env, "kill");
int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid };
struct kinfo_proc kiproc;
size_t kipsz = sizeof(struct kinfo_proc);
/*
* Early in the lifetime of a JVM it has not yet initialized its signal handlers, in particular the QUIT
* handler, note that the default behavior of QUIT is to terminate the receiving process, if unhandled.
*
* Since we use QUIT to initiate an attach operation, if we signal a JVM during this period early in its
* lifetime before it has initialized its QUIT handler, such a signal delivery will terminate the JVM we
* are attempting to attach to!
*
* The following code guards the QUIT delivery by testing the current signal masks. It is okay to send QUIT
* if the signal is caught but not ignored, as that implies a handler has been installed.
*/
if (sysctl(mib, sizeof(mib) / sizeof(int), &kiproc, &kipsz, NULL, 0) == 0) {
const bool ignored = (kiproc.kp_proc.p_sigignore & sigmask(SIGQUIT)) != 0;
const bool caught = (kiproc.kp_proc.p_sigcatch & sigmask(SIGQUIT)) != 0;
// note: obviously the masks could change between testing and signalling however this is not the
// observed behavior of the current JVM implementation.
if (caught && !ignored) {
if (kill((pid_t)pid, SIGQUIT) != 0) {
JNU_ThrowIOExceptionWithLastError(env, "kill");
} else {
return JNI_TRUE;
}
} else if (throwIfNotReady) {
char msg[100];
snprintf(msg, sizeof(msg), "pid: %d, state is not ready to participate in attach handshake!", (int)pid);
JNU_ThrowByName(env, "com/sun/tools/attach/AttachNotSupportedException", msg);
}
} else {
JNU_ThrowIOExceptionWithLastError(env, "sysctl");
}
return JNI_FALSE;
}
/*

View File

@@ -756,9 +756,6 @@ jdk/jfr/event/compiler/TestCodeSweeper.java 8338127 generic-
jdk/jfr/event/oldobject/TestShenandoah.java 8342951 generic-all
jdk/jfr/event/runtime/TestResidentSetSizeEvent.java 8309846 aix-ppc64
jdk/jfr/jvm/TestWaste.java 8282427 generic-all
jdk/jfr/api/consumer/streaming/TestJVMCrash.java 8344671 macosx-all
jdk/jfr/api/consumer/streaming/TestJVMExit.java 8344671 macosx-all
jdk/jfr/api/consumer/streaming/TestOutOfProcessMigration.java 8344671 macosx-all
############################################################################