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.

kostix
  • 51,517
  • 14
  • 93
  • 176
Eugene
  • 257
  • 1
  • 6
  • Are you checking the error from the syscall? syscall.Kill should work just like kill from the commandline – JimB Apr 11 '14 at 17:18
  • 1
    Are you positive you're sending your signal to the right PID? – kostix Apr 11 '14 at 17:50
  • PID is correct. It is automatically taken from `run.pid` file and `PID` is printed on screen. So `PID` is correct. – Eugene Apr 11 '14 at 17:58
  • `syscall.Kill` returns `nil` – Eugene Apr 11 '14 at 18:10
  • 2
    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? – Dato Apr 11 '14 at 20:40
  • 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. – Eugene Apr 11 '14 at 22:06
  • 2
    I now wonder: are you daemonizing in Go, using syscalls? This simply [won't work reliably](https://code.google.com/p/go/issues/detail?id=227) and you might expect all sorts of funny behaviour. – kostix Apr 12 '14 at 06:54
  • @kostix 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 https://gist.github.com/wofeiwo/3634357 – Eugene Apr 12 '14 at 13:19

1 Answers1

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.

kostix
  • 51,517
  • 14
  • 93
  • 176