Different behaviors of recursive read locks in stable and nightly versions

154 points bobbqq

Recent optimizations to RwLock in std::sync have changed the behavior of recursive read locks on Linux.

Switching from stable to nightly will cause the following code to deadlock on Linux.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4a1463bd66bc6914d7ffc6ea8b8f1ac6

https://doc.rust-lang.org/std/sync/struct.RwLock.html warns of this kind of deadlock.

Basically, the write lock has a higher priority than the read lock. When trying to acquire a write lock in between two recursive read locks, the second read lock cannot be acquired, which in turn prevents the release of the first read lock.

RwLock in another popular crate parking\_lot has the same behavior.

This kind of deadlock is common and hard to debug.

To tackle this problem, I have made a static tool to detect deadlock bugs on MIR:

https://github.com/BurtonQin/lockbud

The tool is still at its early stage and any issues or PRs are welcome.

This is an extended work of our PLDI'20 paper on real-world Rust bugs.

https://songlh.github.io/paper/rust-study.pdf

Please refer to our paper for more interesting Rust bugs.