When spawning a process in the case where posix_spawn cannot be used, the spawn code uses fork/execvp. It acquires the environment lock before the fork, with a drop handler that unlocks it. Unfortunately, this is done in both the parent and child processes, and unlocking a lock acquired from another thread is undefined behavior (see pthread_rwlock_unlock and pthread_mutex_unlock).
An example of where this can happen is rustdoc running doctests. It has N threads all spawning rustc processes. It was observed in #82221 that this was frequently causing deadlocks (i686, on a Docker image with glibc 2.23).
PR #82877 reverts the change from mutex to rwlock, but pthread_mutex_unlock is also undefined behavior, we just fortunately have not run into any problems. This should be fixed. This can probably be done by mem::forget'ing the guard.
https://stackoverflow.com/questions/61976745/why-does-rust-rwlock-behave-unexpectedly-with-fork also provides some insight into why unlocking a rwlock after a fork doesn't work.
rustc 1.52.0-nightly (caca212 2021-03-05)
When spawning a process in the case where
posix_spawncannot be used, the spawn code usesfork/execvp. It acquires the environment lock before the fork, with a drop handler that unlocks it. Unfortunately, this is done in both the parent and child processes, and unlocking a lock acquired from another thread is undefined behavior (seepthread_rwlock_unlockandpthread_mutex_unlock).An example of where this can happen is rustdoc running doctests. It has N threads all spawning
rustcprocesses. It was observed in #82221 that this was frequently causing deadlocks (i686, on a Docker image with glibc 2.23).PR #82877 reverts the change from mutex to rwlock, but
pthread_mutex_unlockis also undefined behavior, we just fortunately have not run into any problems. This should be fixed. This can probably be done by mem::forget'ing the guard.https://stackoverflow.com/questions/61976745/why-does-rust-rwlock-behave-unexpectedly-with-fork also provides some insight into why unlocking a rwlock after a fork doesn't work.
rustc 1.52.0-nightly (caca212 2021-03-05)