[GHC] #10081: SIGTERM ignored when process has been detached from terminal

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: | Version: 7.8.3 libraries/unix | Operating System: FreeBSD Keywords: | Type of failure: Incorrect result Architecture: x86_64 | at runtime (amd64) | Blocked By: Test Case: | Related Tickets: Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- I've tried to write a simple Unix daemon that reacts to signals. Here is the reduced source code sample: {{{#!hs import Control.Concurrent import Control.Monad import System.Exit import System.IO import System.Posix.Signals loop = forever $ threadDelay 1000000 main = do ppid <- myThreadId mapM (\sig -> installHandler sig (Catch $ trap ppid) Nothing) [ lostConnection, keyboardSignal, softwareTermination, openEndedPipe ] loop trap tid = do hPutStrLn stderr "Signal received.\n" throwTo tid ExitSuccess }}} Such daemons usually run in background without a terminal attached. I verified that I can kill the process after being started on the terminal: {{{
./daemon Signal received. }}}
With: {{{
killall daemon }}}
in other terminal. Other test, when I run it in background: {{{
./daemon (press Ctrl+Z) bg killall daemon Signal received. }}}
This case is also ok. Now the third test which is also OK: {{{
./daemon > log 2>&1 (press Ctrl+Z) bg exit }}}
In second terminal: {{{
cat log killall daemon cat log Signal received.
killall daemon No matching processes belonging to you were found }}}
Now the fourth test which is simply without a log file and this one fails: {{{
./daemon (press Ctrl+Z) bg exit }}}
On some other terminal try to kill the process: {{{
killall xxx killall xxx killall xxx killall -9 xxx killall xxx No matching processes belonging to you were found }}}
Signal 9 (SIGKILL) kills the process hard without the signal trap. That's why it works, of course, but SIGTERM is being ignored for some reason. Maybe I am forgetting something, but in my opinion this should end the process properly, too. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: libraries/unix | Version: 7.8.3 Resolution: | Keywords: Operating System: FreeBSD | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by rwbarton): Is `openEndedPipe` SIGPIPE? Then, in the last test, as you have exited the shell that invoked the daemon, when you send it a SIGTERM, wouldn't the daemon try to print an error message `trap`, and then receive a SIGPIPE since its stderr is closed, and then enter `trap` again to handle that signal, etc.? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: libraries/unix | Version: 7.8.3 Resolution: | Keywords: Operating System: FreeBSD | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by nakal): As far as I know, SIGPIPE will occur, if a pipe was there, but it's closed later and the main process still tries to write to it. I think detached programs don't get SIGPIPE when they write something to stdout/stderr. I have to mention some more facts here. I tried to catch many more signals to check what happens. My small program originally did not catch SIGPIPE and the behavior is the same. You can try it. There is no endless loop when you send the signal. The process is still idle. I think that the main process still works correctly without interruptions, but I will verify it later to be sure. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: libraries/unix | Version: 7.8.3 Resolution: | Keywords: Operating System: FreeBSD | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by rwbarton): Okay, I tried running it under strace: the `write` from `hPutStrLn` is failing with `EIO`, which then gets turned into an exception, meaning `throwTo tid ExitSuccess` is never run. Since signals are handled in a new thread, if the signal handler raises an exception, it is reported to stderr (which, in this case, also fails with `EIO`), and the program continues to run. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: libraries/unix | Version: 7.8.3 Resolution: | Keywords: Operating System: FreeBSD | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by nakal): So the problem is that the exception that tries to output the cause to stderr also runs in the same problem as my trap function. Probably, this is not an intended behavior. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: libraries/unix | Version: 7.8.3 Resolution: | Keywords: Operating System: FreeBSD | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by pgj): Replying to [comment:3 rwbarton]:
Okay, I tried running it under strace
Did you try to diagnose this on FreeBSD, or did you do this on some other system, such as Linux? I am asking because if the problem appears on systems other than FreeBSD, I would like to recommend to change the "Operating System" field of the ticket to reflect that this issue is system independent. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: libraries/unix | Version: 7.8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by rwbarton): * os: FreeBSD => Unknown/Multiple Comment: Indeed, I am testing on Linux. However, I don't understand why this behavior is unexpected. The thread in which the signal handler runs dies due to an uncaught exception from `hPutStrLn`, and so the `throwTo` is never reached. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: libraries/unix | Version: 7.8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by nakal): Did you try to catch the exception at hPutStrLn? Maybe I did something wrong, but I could not work around it. Can you paste some code, so I can verify this? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: ekmett Type: bug | Status: new Priority: normal | Milestone: Component: Core Libraries | Version: 7.8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by argiopeweb): * cc: core-libraries-committee@… (added) * owner: => ekmett * component: libraries/unix => Core Libraries Comment: Passed upstream as https://github.com/haskell/unix/issues/38 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: ekmett Type: bug | Status: new Priority: normal | Milestone: Component: Core Libraries | Version: 7.8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by rwbarton): nakal: consider this program for instance {{{ import Control.Concurrent import Control.Exception import Control.Monad import System.Exit import System.IO import System.Posix.Signals loop = forever $ threadDelay 1000000 main = do ppid <- myThreadId mapM (\sig -> installHandler sig (Catch $ trap ppid) Nothing) [ keyboardSignal ] loop trap tid = do hPutStrLn stderr "Signal received.\n" throwIO Overflow throwTo tid ExitSuccess }}} If you run it in a terminal and press ctrl-C, you will see {{{ ^CSignal received. u: arithmetic overflow }}} and the program will keep running. ---- To catch the exception from `hPutStrLn` you can simply do {{{ import Control.Exception import Control.Concurrent import Control.Monad import System.Exit import System.IO import System.Posix.Signals loop = forever $ threadDelay 1000000 main = do ppid <- myThreadId mapM (\sig -> installHandler sig (Catch $ trap ppid) Nothing) [ lostConnection, keyboardSignal, softwareTermination, openEndedPipe ] loop trap tid = do let handler :: SomeException -> IO () handler _ = return () catch (hPutStrLn stderr "Signal received.\n") handler throwTo tid ExitSuccess }}} and now the program exits when run and killed as in your fourth test. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: ekmett Type: bug | Status: new Priority: normal | Milestone: Component: Core Libraries | Version: 7.8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by nakal): I want to confirm that your solution works. Thank you. I tried before with `bracket`. I guess, I messed up something. Also, I find the behavior a bit strange (default ignoring of exceptions in trap handler), but I guess it is OK in this way. You can close this report. It has been my misunderstanding how exceptions work in signal handlers. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10081: SIGTERM ignored when process has been detached from terminal -------------------------------------+------------------------------------- Reporter: nakal | Owner: ekmett Type: bug | Status: closed Priority: normal | Milestone: Component: Core Libraries | Version: 7.8.3 Resolution: invalid | Keywords: Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by rwbarton): * status: new => closed * resolution: => invalid Comment:
I tried before with `bracket`.
Ah, but `bracket` reraises the exception after running the cleanup action, so that's why the `throwTo` was still not reached. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10081#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC