Disabling GO SIGINT handling on Windows


(Soleil Lapierre) #1

My team is publishing a Go shared library containing our business logic, with wrappers in several other languages. We’re having a problem on Windows only where user signal handlers do not get invoked if they import our library. For example, in Python:

from signal import signal, SIGINT
# import our library here (or anywhere below; order makes no difference)

def handler(signal_received, frame):
    print('Cleaning up')
    exit(0)

if __name__ == '__main__':
    signal(SIGINT, handler)

    print('Running. Press CTRL-C to exit.')
    # Main loop goes here.

Running this code as-is and pressing CTRL-C causes the “Cleaning up” message to print, which is the expected result. But it they add an import statement for our library anywhere in this code, the message no longer prints. This works fine on Linux but breaks on Windows, and not just in Python; we observed the same effect in JavaScript but haven’t tested in other languages yet.

The use case for this is to shut down equipment automatically when someone stops the controlling script.

From this ticket and from looking at the Go source code, it looks like Go always installs its own handler for SIGINT on Windows, which just kills the program when CTRL-C is pressed.

I can use signal.Ignore(os.Interrupt) to disable that, but it doesn’t restore the default handler. I can use signal.Notify(channel, os.Interrupt) to handle the signal in our Go code, but re-raising it via a CGo function in our Go handler just creates an infinite loop.

I could invoke a callback in the user language that would raise the signal over there, but that will not cause the user’s handler to be invoked automatically - I tested this by adding os.kill(os.getpid(), signal.SIGABRT) to the Python example above.

That leaves me with creating API for users to provide a callback specific to this purpose, which is inelegant because the expectation is that they should be able to use their language’s own facilities for this.

So far I have not spotted a way to make Go leave the SIGINT handler alone or restore the original one. There is a Windows-specific note at the bottom of the signal documentation that basically says your options are hard exit or handling it in Go.

Is anyone aware of some option to allow other-language signal handlers to still work on Windows?


(Soleil Lapierre) #2

Resolution: We were unable to find a workaround for this and have decided to file a bug report instead: https://github.com/golang/go/issues/35965