How do I trigger the default signal handling behavior?

青春壹個敷衍的年華 提交于 2019-12-05 15:41:21

I think the key to the mystery here is that SIG_DFL is not the original handler for SIGINT.

The following code worked for me:

    Signal sigInt = new Signal("INT");

    // First register with SIG_DFL, just to get the old handler.
    final SignalHandler oldHandler = Signal.handle(sigInt, SignalHandler.SIG_DFL );

    // Now register the actual handler
    Signal.handle(sigInt, new SignalHandler(){

        @Override
        public void handle(Signal signal) {
            System.err.println("Sigint is being handled");
            oldHandler.handle(signal);
        }

    });

This does not cause the segmentation violation, and instead terminates the program as expected (after printing the sample text).

dimo414

Credit for originally noticing this goes to RealSkeptic, but I wanted to expand on it in an answer.

The default behavior for SIGINT, SIGTERM, and SIGHUP is not, in fact, SignalHandler.SIG_DFL. Instead, the java.lang.Terminator class registers a SignalHandler that does, in fact, simply call Shutdown.exit():

SignalHandler sh = new SignalHandler() {
    public void handle(Signal sig) {
      Shutdown.exit(sig.getNumber() + 0200);
    }
};

You can capture this SignalHandler by calling Signal.handle() (since it returns the old handler), or you can simply define your own handler that calls System.exit() which will do the same thing.

Note that Terminator's call to Shutdown.exit() is not exactly the same as System.exit(). The former is package-private, meaning you can't call it directly. If a security manager prevents you from calling System.exit(), you'll have to capture the original handler and reuse it.

Warning: this is undocumented behavior. It's unlikely but entirely possible that future releases of Java could change this behavior.

Ben

Exiting with 128+signal number seems to be typical on Unix/Linux.

For more evidence, see also:

Browsing the source code on OpenJDK suggests that the default behaviour is to allow the underlying C Runtime or OS default action to proceed.

In any case this is only typical behaviour, and as you point out is not documented. Exit codes are not standardized - generally there is a convention that zero means success, and nonzero failure, but even the first part is not always adhered to. Therefore it is for you to define your own exit codes.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!