Graal: native-image should register SIGTERM handler when it is the init process

Created on 9 Aug 2019  路  7Comments  路  Source: oracle/graal

Currently, Graal native images don't register a SIGTERM handler, for reasons described here:

https://github.com/oracle/graal/issues/465#issuecomment-397463200

That's fine, unless the Graal native image is the init process (ie, has pid 1), which it is if it's the entry point for a docker container (or any container). Since Linux treats init processes specially, ie, it does not implement a default SIGTERM handler if the process doesn't register one itself, this means using a Graal image as a Docker entry point will mean that the container can never be stopped, only killed (though Docker does send sigkill to the process after a certain timeout if it doesn't respond to siterm, by default 10 seconds).

So, I think at very least, Graal native images should register a sigterm handler when its pid is 1 - this handler doesn't necessarily have to implement the System.exit() logic, it could just invoke the exit system call. That way it would be consistent with when the pid isn't 1, leaving the user to be responsible for overriding the handler if they want shutdown hooks to be executed.

native-image spring

Most helpful comment

The fix is on master and on the 20.1 branch. Using native-image option --install-exit-handlers gives you the same exit handlers that also the JVM provides. I.e. if you build an image that should work nicely in docker containers make sure to build with --install-exit-handlers.

All 7 comments

I鈥檇 very much like to see shutdown hooks supported like in the regular JVM. I understand that it鈥檚 not desirable to register the default signal handlers when we鈥檙e building something to be embedded (this means when we鈥檙e building a shared library, right?).

To me, though, it makes a lot of sense to run the default signal handlers when we鈥檙e building an executable, so that we鈥檙e compatible with the regular JVM. This could maybe be disabled with a command line switch?

At present, you have to do awkward things like:

package com.example;

import io.micronaut.runtime.Micronaut;
import sun.misc.Signal;
import sun.misc.SignalHandler;

public class Application {
    public static void main(String[] args) {
        SignalHandler sh = sig -> System.exit(128 + sig.getNumber());
        Signal.handle(new Signal("INT"), sh);
        Signal.handle(new Signal("TERM"), sh);

        Micronaut.run(Application.class);
    }
}

in many frameworks, causing a bunch of compiler warnings, and un-necessary boilerplate code.

Same point - one of the most obvious use cases for native-image is to build containerized apps and it's such a prevalent use case it would probably make sense to add a flag-based toggle to include signal handlers in generated binaries. Maybe something like --add-signal-handlers? Maybe limit it to what @jroper proposed - work only for PID 1 (one concern I have here is that for some images native image won't be PID 1, because it will be executed by some shell script for instance)?

The fix is on master and on the 20.1 branch. Using native-image option --install-exit-handlers gives you the same exit handlers that also the JVM provides. I.e. if you build an image that should work nicely in docker containers make sure to build with --install-exit-handlers.

@olpaw, I just saw this after making a comment on #465, could the documentation on https://www.graalvm.org/reference-manual/native-image/ (or it's child pages) be updated to mention this option?

@olpaw, I just saw this after making a comment on #465, could the documentation on https://www.graalvm.org/reference-manual/native-image/ (or it's child pages) be updated to mention this option?

@olyagpl please make sure we have --install-exit-handlers mentioned in the docs.

@olpaw, the command option is now mentioned on https://github.com/oracle/graal/blob/master/substratevm/README.md#build-a-native-image and options pages.

Was this page helpful?
0 / 5 - 0 ratings