8305507: Add support for grace period before AbortVMOnSafepointTimeout triggers

Reviewed-by: dholmes, pchilanomate
This commit is contained in:
Wojciech Kudla 2023-09-05 14:12:45 +00:00 committed by Patricio Chilano Mateo
parent ed2b4673de
commit cef9fff067
3 changed files with 58 additions and 3 deletions

View File

@ -430,6 +430,10 @@ const int ObjectAlignmentInBytes = 8;
product(bool, AbortVMOnSafepointTimeout, false, DIAGNOSTIC, \
"Abort upon failure to reach safepoint (see SafepointTimeout)") \
\
product(uint64_t, AbortVMOnSafepointTimeoutDelay, 0, DIAGNOSTIC, \
"Delay in milliseconds for option AbortVMOnSafepointTimeout") \
range(0, max_jlong) \
\
product(bool, AbortVMOnVMOperationTimeout, false, DIAGNOSTIC, \
"Abort upon failure to complete VM operation promptly") \
\

View File

@ -808,7 +808,7 @@ void SafepointSynchronize::print_safepoint_timeout() {
// To debug the long safepoint, specify both AbortVMOnSafepointTimeout &
// ShowMessageBoxOnError.
if (AbortVMOnSafepointTimeout) {
if (AbortVMOnSafepointTimeout && (os::elapsedTime() * MILLIUNITS > AbortVMOnSafepointTimeoutDelay)) {
// Send the blocking thread a signal to terminate and write an error file.
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur_thread = jtiwh.next(); ) {
if (cur_thread->safepoint_state()->is_running()) {

View File

@ -28,7 +28,8 @@ import jdk.test.whitebox.WhiteBox;
/*
* @test TestAbortVMOnSafepointTimeout
* @summary Check if VM can kill thread which doesn't reach safepoint.
* @summary Check if VM can kill thread which doesn't reach safepoint,
* test grace period before AbortVMOnSafepointTimeout kicks in
* @bug 8219584 8227528
* @requires vm.flagless
* @library /testlibrary /test/lib
@ -39,7 +40,7 @@ import jdk.test.whitebox.WhiteBox;
public class TestAbortVMOnSafepointTimeout {
public static void main(String[] args) throws Exception {
public static void testThreadKilledOnSafepointTimeout() throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xbootclasspath/a:.",
"-XX:+UnlockDiagnosticVMOptions",
@ -56,6 +57,31 @@ public class TestAbortVMOnSafepointTimeout {
);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
verifyAbortVmApplied(output);
}
public static void testGracePeriodAppliedBeforeVmAbort() throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xbootclasspath/a:.",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
"-XX:+SafepointTimeout",
"-XX:+SafepointALot",
"-XX:+AbortVMOnSafepointTimeout",
"-XX:AbortVMOnSafepointTimeoutDelay=2500",
"-XX:SafepointTimeoutDelay=50",
"-XX:GuaranteedSafepointInterval=1",
"-XX:-CreateCoredumpOnCrash",
"-Xms64m",
"TestAbortVMOnSafepointTimeout$TestWithDelay"
);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain(TestWithDelay.PRE_STALL_TEXT);
verifyAbortVmApplied(output);
}
private static void verifyAbortVmApplied(OutputAnalyzer output) {
output.shouldContain("Timed out while spinning to reach a safepoint.");
if (Platform.isWindows()) {
output.shouldContain("Safepoint sync time longer than");
@ -68,6 +94,14 @@ public class TestAbortVMOnSafepointTimeout {
output.shouldNotHaveExitValue(0);
}
public static void main(String[] args) throws Exception {
// test basic AbortVMOnSafepointTimeout functionality
testThreadKilledOnSafepointTimeout();
// verify -XX:AbortVMOnSafepointTimeoutDelay functionality
testGracePeriodAppliedBeforeVmAbort();
}
public static class Test {
public static void main(String[] args) throws Exception {
Integer waitTime = Integer.parseInt(args[0]);
@ -78,4 +112,21 @@ public class TestAbortVMOnSafepointTimeout {
}
}
}
public static class TestWithDelay {
public static final String PRE_STALL_TEXT = "THE FOLLOWING STALL SHOULD BE CAPTURED";
public static void main(String[] args) throws Exception {
WhiteBox wb = WhiteBox.getWhiteBox();
// induce a stall that should not be picked up before grace period
wb.waitUnsafe(999);
System.out.println(PRE_STALL_TEXT);
// trigger safepoint timeout
while (true) {
wb.waitUnsafe(999);
}
}
}
}