-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Open
Description
golang/go#22315 sets out the issue.
Fundamentally, this seems like an inescapable race in multi-threaded programs on Linux.
My understanding of the failure is this:
- A process with two threads wants to write a file and then execute it.
- Thread 1 opens a file for writing
- Thread 2 issues a call to create a new process and completes a
forkcall. - The new process inherits all file descriptors open in Process 1, including the file opened by Thread 1.
- Thread 1 finishes writing and closes the file descriptor.
- Thread 1 attempts to execute the file.
- Linux produces ETXTBSY ("Text file is busy") because Process 2 still has an open handle to the file.
I don't see a way to completely prevent this race, as there's no way to avoid executing fork to create a new process on Linux. However, there are two mitigations we could consider:
- Unix supports a FD_CLOEXEC flag on file descriptors, which indicates that the file descriptor should be closed after a call to
exec. Since the "new process" procedure in Unix isfork+exec, this would narrow the window of the race to just afterforkand just beforeexec. It may be possible to always set this flag when opening file descriptors on Linux from managed code -- we don't supportforkwithoutexecand inheriting non-tty open file descriptors does not appear to be in any .NET contract. - Introduce a retry into Process.Create if encountering
ETXTBSY. This could workaround the issue, at the expense of taking longer to fail in a real contention situation.
Reactions are currently unavailable