[Haskell-cafe] Can't figure out source of race condition when using System.Process

Rafal Kolanski xs at xaph.net
Mon Nov 3 07:49:41 EST 2008


Bryan O'Sullivan wrote:
> What is the "it" that segfaults? The Haskell program shouldn't, at least.

The Haskell program. It does so rarely, however, and I'm unable to 
reproduce it with any consistency, only enough to notice something is 
wrong with what I've written.
Upon closer examination my code also returns an error exit code for 
subprocesses that should've succeeded (pdflatex, but once in a blue moon 
also pstoedit) similarly rarely.

> That said, your code for reading from child processes is wrong. You 
> should read all of a child's output strictly (i.e. hGetContents alone 
> will not do the trick) before you wait for its exit status. Your current 
> scheme reverses this order, and there is hence no guarantee that it will 
> read anything from the defunct child process. There's some possibility 
> that this might be the cause of your segfault, which to me would suggest 
> the presence of a bug in the runtime system.

Well, if there's a bug in the runtime system, I'll try to make sure I 
can reproduce it before filing a report.

Meanwhile, you are absolutely right. How would you propose I properly 
perform that sort of interaction? It's often useful to use external 
programs to do things for you by throwing data at them and reading (or 
ignoring) the result until they die. Is there a Haskell idiom for this?

Overall, I find Haskell to be very nice. I just keep getting bitten by 
laziness, at least until I get used to it.

Sincerely,

Rafal Kolanski.

PS. The file I attached is the only real place where concurrency happens 
in my code. The rest of the uses are simple ... when rendering a slide 
using cairo:

slideNaive = do
	...
	paintLatex "\\textbf{datatype} ref = Ref int $\\mid$ Null" 50 0
	...

which calls:

paintLatex text x y = do
     svg <- liftIO $ updateSVG text
     paintSVG svg 3 x y

updateSVG is defined in SVGLatex.hs which I attached earlier, and the rest:

paintSVG :: FilePath -> Double -> Double -> Double -> Render ()
paintSVG file scale' x y = do
     save
     svg <- liftIO $ svgNewFromFile file
     let (w,h) = svgGetSize svg
     translate x y
     scale scale' scale'
     moveTo 0 0
     svgRender svg
     restore

which invokes functions defined in:
import Graphics.Rendering.Cairo
import Graphics.Rendering.Cairo.SVG


More information about the Haskell-Cafe mailing list