Unable to `syscall.Kill()` a daemonized Go process
Asked Answered
C

1

6

I made program in Go that kills a process with syscall.Kill()

But if I daeminze that process with fork() + setsid() then syscall.Kill() does not kill that process.

If I use shell kill then I'm able to kill that process in both cases.

I tried different signals: SIGINT, SIGTERM and SIGKILL buthey do not kill the daemon.

Canada answered 11/4, 2014 at 16:33 Comment(8)
Are you checking the error from the syscall? syscall.Kill should work just like kill from the commandlineHarkness
Are you positive you're sending your signal to the right PID?Imitate
PID is correct. It is automatically taken from run.pid file and PID is printed on screen. So PID is correct.Canada
syscall.Kill returns nilCanada
What is run.pid? If syscall.Kill() is working, and then adding fork() makes it stop working, then it sounds plausible that you're killing the initial process, and not the child one. Did you collate PID not only with run.pid, but also the output of ps aux?Hamlett
I get syscall.Getpid() after fork. I print PID that I pass to syscall.Kill(). It seems I am unable to start web server in daemon also. I even tried to use unix sockets. It creates socket file but control is not working. But daemon is able to run subprocess that is able to start webserver. Is there something related to permissions that block daemonized process from listening. If I do not daemonize process then everyting works. (Signals, WebServers, Unix Sockets) It is very odd that I can't kill that process. It looks like it is dead and not working.Canada
I now wonder: are you daemonizing in Go, using syscalls? This simply won't work reliably and you might expect all sorts of funny behaviour.Imitate
@Imitate that is an answer! Please post your last comment as answer and I will mark it as answer. How to daemonize in Go is another question and I will go with nohup right now. I used code inspired with gist.github.com/wofeiwo/3634357Canada
I
6

Daemonizing a Go process using syscalls is not currently possible to do reliably and that's why your sort-of-daemonized process was impossible to kill: it has been wedged (though I should admit it's weird why it did not die in response to sending SIGKILL which makes the kernel just destroy the process, no signal delivery is attempted).

To properly daemonize a Go process one is advised to use a wrapper process (such as daemon) or run it under an an advanced substitute for the init superserver such as systemd or upstart or a standalone supervisor such as runit, monit and others—in which case the process has no braindead requirement to be a true Unix daemon and may behave like a normal process: does not perform double-fork+setsid trickery, does not mess with PID file management, is able to write to its regular I/O streams etc.

Imitate answered 12/4, 2014 at 19:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.