Child processes always unwantedly inherit Handles on Windows
runInteractiveProcess
(the one in runProcess.c
, not the Haskell one) calls CreateProcess
with bInheritHandles
set to TRUE
, but the whole thing is not wrapped in a critical section. Microsoft has a decent explanation of why this is a problem and I found that it's a two-year old unfixed bug in the Java runtime as well.
In case it's not obvious, the reason why we don't want Handles to be inherited is that then a child process may hang on to it well after it should have been closed. The end result is that trying to do anything to it results in a sharing violation. The case in which I originally ran into this was System.Directory.copyFile
intermittently reporting a "permission denied" error for a temp file it was using. I think it was trying to delete it, but failing because a child process somewhere was hanging on to the Handle.
Attached is code demonstrating the problem. It forks a thread which repeatedly tries to open and close the file foo.tmp
. The main thread then spawns processes as fast as it can until the other one fails to open the file. This, I think, cannot happen on non-Windows platforms since two processes can have the same file open without trouble. Do not run except on Windows, you risk flooding your system with ping
processes.
It may be sensible to make this controllable with the close_fds
parameter to createProcess
, which is currently just ignored on Windows. I can't see why anybody could ever want this behaviour, though.
I've tested only process-1.0.1 with it, and the openFile
fails reliably after spawning up to about 4 processes.
Trac metadata
Trac field | Value |
---|---|
Version | 6.9 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | libraries/process |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture | x86 |