Grodriguez
Grodriguez

Reputation: 21995

Child process ignores SIGQUIT if started from Java

Take this simple example:

public class Main
{
    public static void main(String[] args) throws Exception
    {
        Runtime.getRuntime().exec("sleep 1000");

        // This is just so that the JVM does not exit
        Thread.sleep(1000 * 1000);
    }
}

I am running this on Linux using openjdk6. If I try to send a SIGQUIT signal to the "sleep" process, it ignores it. Other signals (SIGINT, SIGTERM etc) all work fine, but SIGQUIT is ignored. If I just run sleep 1000 from a shell without using Java, then SIGQUIT is handled properly.

Why is the behaviour different?

Upvotes: 3

Views: 1119

Answers (1)

Mark Plotnick
Mark Plotnick

Reputation: 10261

Pass java the -Xrs option. I have tested your program with and without the option. Without the option, SIGQUIT is blocked; with it, the signal is not blocked and the sleep process is terminated when I send it a SIGQUIT signal.

The closest explanation I can find about what's going on is in the OpenJDK 6 java(1) man page:

Sun's JVM catches signals to implement shutdown hooks for abnormal JVM termination. The JVM uses SIGHUP, SIGINT, and SIGTERM to initiate the running of shutdown hooks.

The JVM uses a similar mechanism to implement the pre-1.2 feature of dumping thread stacks for debugging purposes. Sun's JVM uses SIGQUIT to perform thread dumps.

Applications embedding the JVM frequently need to trap signals like SIGINT or SIGTERM, which can lead to interference with the JVM's own signal handlers. The -Xrs command-line option is available to address this issue. When -Xrs is used on Sun's JVM, the signal masks for SIGINT, SIGTERM, SIGHUP, and SIGQUIT are not changed by the JVM, and signal handlers for these signals are not installed.

Upvotes: 5

Related Questions