ADDITIONAL SYSTEM INFORMATION :
Tested on Linux and macOS, Java 8, 11, 17, and 21. By code inspection, all supported platforms and versions.
A DESCRIPTION OF THE PROBLEM :
The -Xrs flag is documented as allowing a Java program to register signal handlers for the TERM, HUP, and INT signals on Posix (and an equivalent set of signals on Windows); otherwise attempts to register those signal handlers should fail.
However, the exact opposite is the case -- signal handlers for those signals can be registered *unless* -Xrs is set.
This appears to be a missing negation in the implementation of JVM_RegisterSignal.
Given that this appears to have been the case for a great many Java releases now -- git history shows at least 13 years -- I suspect it would be better to fix the documentation of -Xrs and sun.misc.Signal than to change the behavior at this point, even though sun.misc.Signal is technically an unsupported API.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached Java program, with and without the -Xrs flag.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Expected Result
$ java CatchSignal CatchSignal.class
Exception in thread "main" java.lang.IllegalArgumentException: Signal already used by VM or OS: SIGTERM
at java.base/jdk.internal.misc.Signal.handle(Signal.java:173)
at jdk.unsupported/sun.misc.Signal.handle(Signal.java:157)
at CatchSignal.main(CatchSignal.java:12)
$ java -Xrs CatchSignal CatchSignal.class
^CGot signal, exiting.
ACTUAL -
$ java CatchSignal CatchSignal.class
Exception in thread "main" java.lang.IllegalArgumentException: Signal already used by VM or OS: SIGTERM
at java.base/jdk.internal.misc.Signal.handle(Signal.java:173)
at jdk.unsupported/sun.misc.Signal.handle(Signal.java:157)
at CatchSignal.main(CatchSignal.java:12)
$ java -Xrs CatchSignal CatchSignal.class
^CGot signal, exiting.
---------- BEGIN SOURCE ----------
import java.util.concurrent.CountDownLatch;
import sun.misc.Signal;
public class CatchSignal {
private static CountDownLatch gotSignal = new CountDownLatch(1);
private static String[] signals = new String[]{"TERM", "HUP", "INT"};
public static void main(String[] args) {
for (String signalName: signals) {
Signal.handle(new Signal(signalName), (Signal sig) -> {
gotSignal.countDown();
});
}
try {
gotSignal.await();
} catch (InterruptedException ignored) {}
System.out.println("Got signal, exiting.");
}
}
---------- END SOURCE ----------
Tested on Linux and macOS, Java 8, 11, 17, and 21. By code inspection, all supported platforms and versions.
A DESCRIPTION OF THE PROBLEM :
The -Xrs flag is documented as allowing a Java program to register signal handlers for the TERM, HUP, and INT signals on Posix (and an equivalent set of signals on Windows); otherwise attempts to register those signal handlers should fail.
However, the exact opposite is the case -- signal handlers for those signals can be registered *unless* -Xrs is set.
This appears to be a missing negation in the implementation of JVM_RegisterSignal.
Given that this appears to have been the case for a great many Java releases now -- git history shows at least 13 years -- I suspect it would be better to fix the documentation of -Xrs and sun.misc.Signal than to change the behavior at this point, even though sun.misc.Signal is technically an unsupported API.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached Java program, with and without the -Xrs flag.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Expected Result
$ java CatchSignal CatchSignal.class
Exception in thread "main" java.lang.IllegalArgumentException: Signal already used by VM or OS: SIGTERM
at java.base/jdk.internal.misc.Signal.handle(Signal.java:173)
at jdk.unsupported/sun.misc.Signal.handle(Signal.java:157)
at CatchSignal.main(CatchSignal.java:12)
$ java -Xrs CatchSignal CatchSignal.class
^CGot signal, exiting.
ACTUAL -
$ java CatchSignal CatchSignal.class
Exception in thread "main" java.lang.IllegalArgumentException: Signal already used by VM or OS: SIGTERM
at java.base/jdk.internal.misc.Signal.handle(Signal.java:173)
at jdk.unsupported/sun.misc.Signal.handle(Signal.java:157)
at CatchSignal.main(CatchSignal.java:12)
$ java -Xrs CatchSignal CatchSignal.class
^CGot signal, exiting.
---------- BEGIN SOURCE ----------
import java.util.concurrent.CountDownLatch;
import sun.misc.Signal;
public class CatchSignal {
private static CountDownLatch gotSignal = new CountDownLatch(1);
private static String[] signals = new String[]{"TERM", "HUP", "INT"};
public static void main(String[] args) {
for (String signalName: signals) {
Signal.handle(new Signal(signalName), (Signal sig) -> {
gotSignal.countDown();
});
}
try {
gotSignal.await();
} catch (InterruptedException ignored) {}
System.out.println("Got signal, exiting.");
}
}
---------- END SOURCE ----------