Skip to content

Commit d979bd8

Browse files
lpgckevinjwalls
authored andcommitted
8344671: Few JFR streaming tests fail with application not alive error on MacOS 15
Reviewed-by: dholmes, kevinw
1 parent 49cb7aa commit d979bd8

File tree

3 files changed

+57
-16
lines changed

3 files changed

+57
-16
lines changed

src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,32 +72,35 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
7272
if (!socket_file.exists()) {
7373
File f = createAttachFile(pid);
7474
try {
75-
sendQuitTo(pid);
75+
checkCatchesAndSendQuitTo(pid, false);
7676

7777
// give the target VM time to start the attach mechanism
7878
final int delay_step = 100;
7979
final long timeout = attachTimeout();
80-
long time_spend = 0;
80+
long time_spent = 0;
8181
long delay = 0;
82+
83+
boolean timedout = false;
8284
do {
8385
// Increase timeout on each attempt to reduce polling
8486
delay += delay_step;
8587
try {
8688
Thread.sleep(delay);
8789
} catch (InterruptedException x) { }
8890

89-
time_spend += delay;
90-
if (time_spend > timeout/2 && !socket_file.exists()) {
91+
timedout = (time_spent += delay) > timeout;
92+
93+
if (time_spent > timeout/2 && !socket_file.exists()) {
9194
// Send QUIT again to give target VM the last chance to react
92-
sendQuitTo(pid);
95+
checkCatchesAndSendQuitTo(pid, !timedout);
9396
}
94-
} while (time_spend <= timeout && !socket_file.exists());
97+
} while (!timedout && !socket_file.exists());
9598
if (!socket_file.exists()) {
9699
throw new AttachNotSupportedException(
97100
String.format("Unable to open socket file %s: " +
98101
"target process %d doesn't respond within %dms " +
99102
"or HotSpot VM not loaded", socket_path,
100-
pid, time_spend));
103+
pid, time_spent));
101104
}
102105
} finally {
103106
f.delete();
@@ -216,7 +219,7 @@ private File createAttachFile(int pid) throws IOException {
216219

217220
//-- native methods
218221

219-
static native void sendQuitTo(int pid) throws IOException;
222+
static native boolean checkCatchesAndSendQuitTo(int pid, boolean throwIfNotReady) throws IOException, AttachNotSupportedException;
220223

221224
static native void checkPermissions(String path) throws IOException;
222225

src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@
2828
#include <sys/socket.h>
2929
#include <sys/stat.h>
3030
#include <sys/syslimits.h>
31+
#include <sys/sysctl.h>
3132
#include <sys/types.h>
3233
#include <sys/un.h>
3334
#include <errno.h>
3435
#include <fcntl.h>
3536
#include <signal.h>
37+
#include <stdbool.h>
3638
#include <stdio.h>
3739
#include <stdlib.h>
3840
#include <string.h>
@@ -110,15 +112,54 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_connect
110112

111113
/*
112114
* Class: sun_tools_attach_VirtualMachineImpl
113-
* Method: sendQuitTo
115+
* Method: checkCatchesAndSendQuitTo
114116
* Signature: (I)V
115117
*/
116-
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_sendQuitTo
117-
(JNIEnv *env, jclass cls, jint pid)
118+
JNIEXPORT jboolean JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkCatchesAndSendQuitTo
119+
(JNIEnv *env, jclass cls, jint pid, jboolean throwIfNotReady)
118120
{
119-
if (kill((pid_t)pid, SIGQUIT)) {
120-
JNU_ThrowIOExceptionWithLastError(env, "kill");
121+
int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid };
122+
123+
struct kinfo_proc kiproc;
124+
size_t kipsz = sizeof(struct kinfo_proc);
125+
126+
/*
127+
* Early in the lifetime of a JVM it has not yet initialized its signal handlers, in particular the QUIT
128+
* handler, note that the default behavior of QUIT is to terminate the receiving process, if unhandled.
129+
*
130+
* Since we use QUIT to initiate an attach operation, if we signal a JVM during this period early in its
131+
* lifetime before it has initialized its QUIT handler, such a signal delivery will terminate the JVM we
132+
* are attempting to attach to!
133+
*
134+
* The following code guards the QUIT delivery by testing the current signal masks. It is okay to send QUIT
135+
* if the signal is caught but not ignored, as that implies a handler has been installed.
136+
*/
137+
138+
if (sysctl(mib, sizeof(mib) / sizeof(int), &kiproc, &kipsz, NULL, 0) == 0) {
139+
const bool ignored = (kiproc.kp_proc.p_sigignore & sigmask(SIGQUIT)) != 0;
140+
const bool caught = (kiproc.kp_proc.p_sigcatch & sigmask(SIGQUIT)) != 0;
141+
142+
// note: obviously the masks could change between testing and signalling however this is not the
143+
// observed behavior of the current JVM implementation.
144+
145+
if (caught && !ignored) {
146+
if (kill((pid_t)pid, SIGQUIT) != 0) {
147+
JNU_ThrowIOExceptionWithLastError(env, "kill");
148+
} else {
149+
return JNI_TRUE;
150+
}
151+
} else if (throwIfNotReady) {
152+
char msg[100];
153+
154+
snprintf(msg, sizeof(msg), "pid: %d, state is not ready to participate in attach handshake!", (int)pid);
155+
156+
JNU_ThrowByName(env, "com/sun/tools/attach/AttachNotSupportedException", msg);
157+
}
158+
} else {
159+
JNU_ThrowIOExceptionWithLastError(env, "sysctl");
121160
}
161+
162+
return JNI_FALSE;
122163
}
123164

124165
/*

test/jdk/ProblemList.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -756,9 +756,6 @@ jdk/jfr/event/compiler/TestCodeSweeper.java 8338127 generic-
756756
jdk/jfr/event/oldobject/TestShenandoah.java 8342951 generic-all
757757
jdk/jfr/event/runtime/TestResidentSetSizeEvent.java 8309846 aix-ppc64
758758
jdk/jfr/jvm/TestWaste.java 8282427 generic-all
759-
jdk/jfr/api/consumer/streaming/TestJVMCrash.java 8344671 macosx-all
760-
jdk/jfr/api/consumer/streaming/TestJVMExit.java 8344671 macosx-all
761-
jdk/jfr/api/consumer/streaming/TestOutOfProcessMigration.java 8344671 macosx-all
762759

763760
############################################################################
764761

0 commit comments

Comments
 (0)