Skip to content

Unix process spawn may trigger UB for pthread lock behavior. #82879

Closed
@ehuss

Description

@ehuss

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions