[Haskell-cafe] threads + IORefs = Segmentation fault?

Peter Verswyvelen bf3 at telenet.be
Sat Jan 19 07:27:47 EST 2008


Hi David,

Which version of GHC are you using?

I tried to recompile some GHC 6.6.1 progs using GHC 6.8.2 and I also got
segfaults. I haven't figured out yet if this is because my changes to
make it work with GHC 6.8.2 are incorrect, or if this is an issue with
6.8.2.

Cheers,
Peter


On Fri, 2008-01-18 at 18:22 -0500, David Roundy wrote:
> Hi all,
> 
> I'm working on some new progress-reporting code for darcs, and am getting
> segmentation faults!  :( The code uses threads + an IORef global variable
> to do this (with lots of unsafePerformIO).  So my question for the gurus
> who know more about this than I do:  is this safe? I thought it would be,
> because only one thread ever modifies the IORef, and the others only read
> it.  I don't really care if they read a correct value, as long as they
> don't segfault.
> 
> The code (to summarize) looks like:
> 
> {-# NOINLINE _progressData #-}
> _progressData :: IORef (Map String ProgressData)
> _progressData = unsafePerformIO $ newIORef empty
> 
> updateProgressData :: String -> (ProgressData -> ProgressData) -> IO ()
> updateProgressData k f = when (progressMode) $ modifyIORef _progressData (adjust f k)
> 
> setProgressData :: String -> ProgressData -> IO ()
> setProgressData k p = when (progressMode) $ modifyIORef _progressData (insert k p)
> 
> getProgressData :: String -> IO (Maybe ProgressData)
> getProgressData k = if progressMode then lookup k `fmap` readIORef _progressData
>                                     else return Nothing
> 
> The key function is
> 
> beginTedious :: String -> IO ()
> beginTedious k = do tid <- forkIO $ handleProgress k
>                     debugMessage $ "Beginning " ++ k
>                     setProgressData k $ ProgressData { sofar = 0,
>                                                        latest = Nothing,
>                                                        total = Nothing,
>                                                        handler = Just tid }
> 
> which is called before an action that may be so tedious for our users that
> they need their day brightened by messages such as "Applying patch
> 137/1436".  The handleProgress function alternates between threadDelay and
> reading the progress data to see whether any progress has been made and
> printing messages.  Meanwhile the main thread calls functions that update
> _progressData.
> 
> Anyhow, the point is that I'm getting segfaults, even after recompiling
> everything from scratch! Is this in fact that unsafe? Do I really need to
> switch to MVars, even though no locking is required?



More information about the Haskell-Cafe mailing list