JDK-8234262 : Unmask SIGQUIT in a child process
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 8,13
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2019-11-15
  • Updated: 2025-05-24
  • Resolved: 2022-09-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 20
20 b17Fixed
Related Reports
Blocks :  
Relates :  
Description
Java blocks SIGQUIT for all JavaThreads. The mask of blocked signals is inherited to the child processes. The ProcessBuilder.start executes the posix_spawn syscall in Java thread so the SIGQUIT is blocked in a child process.
This can be easily seen by cat /proc/<child_pid>/status.
SigPnd:	0000000000000000
ShdPnd:	0000000000000000
SigBlk:	0000000000000004
SigIgn:	0000000000001000
SigCgt:	2000000180000604

The SigBlk: 0000000000000004 is a bitmask 0b100 the signal 3 (SIGQUIT) is blocked.

The JDK code blocking the signals for JavaThread and unblocking them for VMThread is here: https://hg.openjdk.java.net/jdk8u/jdk8u-dev/hotspot/file/9148fcba5de9/src/os/bsd/vm/os_bsd.cpp#l655

The workarund it to run the Java application starting the subprocess with -XX:+ReduceSignalUsage.
Comments
Changeset: 5ae6bc23 Author: Roger Riggs <rriggs@openjdk.org> Date: 2022-09-26 15:55:22 +0000 URL: https://git.openjdk.org/jdk/commit/5ae6bc23e857535532b59aae674e2b917bbf7284
26-09-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/10379 Date: 2022-09-21 20:30:53 +0000
21-09-2022

Processes are launched with posix_spawn, the signal mask of the child can be set without modifying the signal masks of the parent. The signal mask of the child should not mask any signals.
21-09-2022

[~dholmes] Yes, the problem description is right. Users would expect a Java subprocess to behave the same regardless of whether its parent process is another Java process, or a shell script.
20-09-2022

[~manc] so just to be clear about the problem here ... a running JVM has at least one thread prepared to handle SIGQUIT (which is a process directed signal) unless -Xrs is used, in which case SIGQUIT is not unblocked in the signal handling thread. If we spawn a new JVM process from a JavaThread then the new process's main thread has SIGQUIT blocked. If that JVM is passed -Xrs then no thread in the process has SIGQUIT unblocked, so if it is sent to the process it will simply remain pending and not abort the process as expected. The fix would be save the original signal mask in the calling thread, then unblock the desired signals, invoke the fork/exec mechanism, then restore the original signal mask.
19-09-2022

I ran into this problem while trying to write a test for JDK-8292695, see https://github.com/openjdk/jdk/pull/9955#pullrequestreview-1100340825. I was trying to test the behavior of SIGQUIT with "-Xrs". I've attached a repro. Usage: $ TESTJDK=<path_to_a_JDK> $ gcc -I$TESTJDK/include -I$TESTJDK/include/linux -shared -o libTestProcess.so -fpic libTestProcess.c $ $TESTJDK/bin/javac TestProcess.java Launch.java $ $TESTJDK/bin/java Launch $TESTJDK Expected behavior: Child process exits with a nonzero exit code, with "QUIT" or "Quit (core dumped)" on the output. Actual behavior: Child process exits with zero.
09-09-2022

Both Linux and Darwin are affected. Neither posix_spawn nor (v)fork work.
19-11-2019

Is this a problem only on Mac? The issue is OS is labeled Linux but posix_spawn is not the default mode on Linux. Is this a problem for FORK mode as well; see the system property "jdk.lang.Process.launchMechanism". Please set the OS field appropriately.
18-11-2019