Opened 3 years ago

Closed 3 years ago

#8433 closed bug (fixed)

forkProcess masks async exceptions inside the child process

Reported by: joeyh Owned by:
Priority: normal Milestone: 7.8.1
Component: libraries/unix Version: 7.6.3
Keywords: Cc:
Operating System: Linux Architecture: Unknown/Multiple
Type of failure: Incorrect result at runtime Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

Frankly, I'm not sure if this is a bug, but the forkProcess documentation says nothing about it. This can lead to problems when writing a multi-threaded daemon that expects async exceptions to work as they usually would.

FWIW, I have looked at several of the libraries on hackage that handle daemonization, and none of them seem to deal with this by explicitly unmasking exceptions when running the daemon IO action.

Change History (5)

comment:1 Changed 3 years ago by hvr

Here's a simple way to reproduce:

System.Posix.Process.forkProcess $ print =<< Control.Exception.getMaskingState

outputs MaskedInterrupt with GHC 7.6.3 on Linux

comment:2 Changed 3 years ago by hvr

Potential fix:

forkProcess :: IO () -> IO ProcessID
forkProcess action = do
  -- wrap action to re-establish caller's masking state, as
  -- 'forkProcessPrim' starts in 'MaskedInterruptible' state by
  -- default; see also #1048
  mstate <- getMaskingState
  let action' = case mstate of
          Unmasked              -> unsafeUnmask action
          MaskedInterruptible   -> action
          MaskedUninterruptible -> uninterruptibleMask_ action

  bracket
    (newStablePtr (runIO action'))
    freeStablePtr
    (\stable -> throwErrnoIfMinus1 "forkProcess" (forkProcessPrim stable))

comment:3 Changed 3 years ago by Herbert Valerio Riedel <hvr@…>

In 897d66ad9d77d17dae1b5ac94af792e671a76c13/unix:

Fix `forkProcess` to inherit caller's `MaskingState`

...and while at it, use `bracket` to fix a potential resource leak due
to `freeStablePtr` not being called if `throwErrnoIfMinus1` throws an
exception.

This fixes #8433

Signed-off-by: Herbert Valerio Riedel <hvr@gnu.org>

comment:4 Changed 3 years ago by Herbert Valerio Riedel <hvr@…>

In 17192d89e642c463a1987fa3cc5cca2eb546bec7/unix:

Add `forkProcessWithUnmask` function

This seemed to be an obvious addition while working on #8433.

Signed-off-by: Herbert Valerio Riedel <hvr@gnu.org>

comment:5 Changed 3 years ago by hvr

Milestone: 7.8.1
Resolution: fixed
Status: newclosed
Type of failure: None/UnknownIncorrect result at runtime
Note: See TracTickets for help on using tickets.