Possible deadlock by recursive calling of parking_lot::read() in one thread in ethcore client
BurtonQin opened this issue · comments
- Parity Ethereum version: 2.6.4
- Operating system: Windows / MacOS / Linux
- Installation: built from source
- Fully synchronized: yes
- Network: ethereum
- Restarted: no
Following the bug #11172 , which fixes a possible deadlock by recursive calling of parking_lot::read() in one thread in ethcore client,
I parsed the source code and found 4 more recursive calling of parking_lot::read().
I am afraid it is not an easy job to fix all those bugs.
Maybe a code refactoring is required to change the parking_lot::RwLock into other types of rwlock that allow recursive read lock in one thread.
The bugs are located in
- ethcore/src/client/client.rs:386, check_and_lock_block() calls build_last_hashes() on L411
ethcore/src/client/client.rs:931 - ethcore/src/client/client.rs:1949, logs() calls block_number_ref() on L1969
ethcore/src/client/client.rs:1248 & 1250 - ethcore/src/client/client.rs:2102, last_hashes() calls build_last_hashes() on L2102
ethcore/src/client/client.rs:931 - ethcore/src/client/client.rs:2320, prepare_open_block() calls build_last_hashes() on L2331
ethcore/src/client/client.rs:931
The followings are the source code links:
ethcore/src/client/client.rs:386, check_and_lock_block() calls build_last_hashes() on L411
ethcore/src/client/client.rs:931
https://github.com/paritytech/parity-ethereum/blob/6b57429d724c954ad5d64c1b1d42c746f8a4d08e/ethcore/src/client/client.rs#L386-L411
https://github.com/paritytech/parity-ethereum/blob/6b57429d724c954ad5d64c1b1d42c746f8a4d08e/ethcore/src/client/client.rs#L919-L931
ethcore/src/client/client.rs:1949, logs() calls block_number_ref() on L1969
ethcore/src/client/client.rs:1248 & 1250
https://github.com/paritytech/parity-ethereum/blob/6b57429d724c954ad5d64c1b1d42c746f8a4d08e/ethcore/src/client/client.rs#L1949-L1969
https://github.com/paritytech/parity-ethereum/blob/6b57429d724c954ad5d64c1b1d42c746f8a4d08e/ethcore/src/client/client.rs#L1245-L1252
ethcore/src/client/client.rs:2102, last_hashes() calls build_last_hashes() on L2102
ethcore/src/client/client.rs:931
https://github.com/paritytech/parity-ethereum/blob/6b57429d724c954ad5d64c1b1d42c746f8a4d08e/ethcore/src/client/client.rs#L2101-L2103
https://github.com/paritytech/parity-ethereum/blob/6b57429d724c954ad5d64c1b1d42c746f8a4d08e/ethcore/src/client/client.rs#L919-L931
ethcore/src/client/client.rs:2320, prepare_open_block() calls build_last_hashes() on L2331
ethcore/src/client/client.rs:931
https://github.com/paritytech/parity-ethereum/blob/6b57429d724c954ad5d64c1b1d42c746f8a4d08e/ethcore/src/client/client.rs#L2318-L2331
https://github.com/paritytech/parity-ethereum/blob/6b57429d724c954ad5d64c1b1d42c746f8a4d08e/ethcore/src/client/client.rs#L919-L931
I think we could use RwLock::read_recursive in those cases that we know that a read lock
must be held in order to reach there, then it should not deadlock but may starve writers if the read lock is never dropped (if that happens that is a bug)
But perhaps it is better to look into #7079 instead
long-term