Hold cs_main when reading chainActive via getTipLocator(). Remove assumeLocked().#16033
Hold cs_main when reading chainActive via getTipLocator(). Remove assumeLocked().#16033maflcko merged 2 commits intobitcoin:masterfrom
Conversation
|
Can you also delete the LockingStateImpl class? There is no reason for the LockingStateImpl class to exist without assumeLocked. You just need to s/LockingStateImpl/LockImpl/ in the lock method and make LockImpl inherit from UniqueLock. |
This comment has been minimized.
This comment has been minimized.
Thanks, yes that looks perfect. |
|
Could squash all the refactoring except the change to /wallet/wallet.cpp, which could go into a separate commit? |
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
00f9410 to
9402ef0
Compare
|
@MarcoFalke Thanks for the quick review! Updated accordingly. Please re-review :-) |
|
utACK 9402ef0 |
ryanofsky
left a comment
There was a problem hiding this comment.
utACK 00f941055fedb855473d5428f54c9d79786f6e23
|
@ryanofsky Thanks for the review. I think you utACK:ed the previous commit hash :-) |
…(). Remove assumeLocked(). 9402ef0 Remove temporary method assumeLocked(). Remove LockingStateImpl. Remove redundant cs_main locks. (practicalswift) 593a8e8 wallet: Use chain.lock() instead of temporary chain.assumeLocked() (practicalswift) Pull request description: Fixes #16028. Problem description: `LockAnnotation lock(::cs_main)` is a guarantee to the compiler thread analysis that `::cs_main` is locked (when it couldn't be determined otherwise). Despite being annotated with the locking guarantee ... https://github.com/bitcoin/bitcoin/blob/65526fc8666fef35ef908dbc225f706bef642c7e/src/interfaces/chain.cpp#L134-L138 ... `getTipLocator()` reads `chainActive` (via `::ChainActive()`) without holding `cs_main`. This can be verified by adding the following `AssertLockHeld(cs_main)`: ``` $ git diff diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index 5962328..9fc693a0f 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -134,6 +134,7 @@ class LockImpl : public Chain::Lock CBlockLocator getTipLocator() override { LockAnnotation lock(::cs_main); + AssertLockHeld(::cs_main); return ::ChainActive().GetLocator(); } Optional<int> findLocatorFork(const CBlockLocator& locator) override $ make check ../build-aux/test-driver: line 107: 12881 Aborted "$@" > $log_file 2>&1 FAIL: qt/test/test_bitcoin-qt ``` ACKs for commit 9402ef: MarcoFalke: utACK 9402ef0 ryanofsky: utACK 9402ef0. Changes are consolidating commits and removing redundant lock2 cs_main calls Tree-SHA512: 0a030bf0c07eb53194ecc246f973ef389dd42a0979f51932bf94bdf7e90c52473ae03be49718ee1629582b05dd8e0dc020b5a210318c93378ea4ace90c0f9f72
… add run-time check to it 9f85e9c scripted-diff: Rename LockAnnotation to LockAssertion (practicalswift) de9b5db Make sure the compile-time locking promises given via LockAnnotation:s hold also in practice at runtime (ifdef DEBUG_LOCKORDER) (practicalswift) 3a80944 Move LockAnnotation to make it reflect the truth (practicalswift) cc25885 Move LockAnnotation from threadsafety.h (imported code) to sync.h (our code) (practicalswift) Pull request description: `LockAnnotation lock(mutex);` is a guarantee to the compiler thread-analysis that `mutex` is locked (when it couldn't be determined otherwise). Before this PR it was possible to make the mistake of adding a `LockAnnotation` where the correct mutex is _not_ held. This in turn makes the thread-analysis reasoning being based on incorrect premises. This PR adds an assertion in the `LockAnnotation` ctor which checks that the guarantees given by us at compile-time are held also in practice (`ifdef DEBUG_LOCKORDER`). Issues like the one described in #16028 will be discovered immediately with this PR merged. Changes in this PR: * Move `LockAnnotation` from `threadsafety.h` (imported code) to `sync.h` (our code) * Move `LockAnnotation` in `wallet_tests` to make it reflect the truth * Make sure the compile-time locking promises given via `LockAnnotation`:s hold also in practice at runtime (`ifdef DEBUG_LOCKORDER`) * Rename `LockAnnotation` to `LockAssertion` ACKs for commit 9f85e9: ryanofsky: utACK 9f85e9c. No changes at all since last review except clean rebase after base PR #16033 was merged Tree-SHA512: fb80e78fe362adfd6ea8405bcb142c09b99f834fe8be4397282b223ca2c3a2bb9719a074a47a043b44757f840b239a6fcd2f98d14771f8729204834ecf608c3a
…ion and add run-time check to it 9f85e9c scripted-diff: Rename LockAnnotation to LockAssertion (practicalswift) de9b5db Make sure the compile-time locking promises given via LockAnnotation:s hold also in practice at runtime (ifdef DEBUG_LOCKORDER) (practicalswift) 3a80944 Move LockAnnotation to make it reflect the truth (practicalswift) cc25885 Move LockAnnotation from threadsafety.h (imported code) to sync.h (our code) (practicalswift) Pull request description: `LockAnnotation lock(mutex);` is a guarantee to the compiler thread-analysis that `mutex` is locked (when it couldn't be determined otherwise). Before this PR it was possible to make the mistake of adding a `LockAnnotation` where the correct mutex is _not_ held. This in turn makes the thread-analysis reasoning being based on incorrect premises. This PR adds an assertion in the `LockAnnotation` ctor which checks that the guarantees given by us at compile-time are held also in practice (`ifdef DEBUG_LOCKORDER`). Issues like the one described in bitcoin#16028 will be discovered immediately with this PR merged. Changes in this PR: * Move `LockAnnotation` from `threadsafety.h` (imported code) to `sync.h` (our code) * Move `LockAnnotation` in `wallet_tests` to make it reflect the truth * Make sure the compile-time locking promises given via `LockAnnotation`:s hold also in practice at runtime (`ifdef DEBUG_LOCKORDER`) * Rename `LockAnnotation` to `LockAssertion` ACKs for commit 9f85e9: ryanofsky: utACK 9f85e9c. No changes at all since last review except clean rebase after base PR bitcoin#16033 was merged Tree-SHA512: fb80e78fe362adfd6ea8405bcb142c09b99f834fe8be4397282b223ca2c3a2bb9719a074a47a043b44757f840b239a6fcd2f98d14771f8729204834ecf608c3a
…tor(). Remove assumeLocked() Summary: bitcoin/bitcoin@593a8e8 wallet: Use chain.lock() instead of temporary chain.assumeLocked() bitcoin/bitcoin@9402ef0 Remove temporary method assumeLocked(). Remove LockingStateImpl. Remove redundant cs_main locks. --- This is a backport of Core [[bitcoin/bitcoin#16033 | PR16033]] Test Plan: ninja check Reviewers: #bitcoin_abc, deadalnix Reviewed By: #bitcoin_abc, deadalnix Subscribers: deadalnix Differential Revision: https://reviews.bitcoinabc.org/D6132
…Locator(). Remove assumeLocked().
…ion and add run-time check to it 9f85e9c scripted-diff: Rename LockAnnotation to LockAssertion (practicalswift) de9b5db Make sure the compile-time locking promises given via LockAnnotation:s hold also in practice at runtime (ifdef DEBUG_LOCKORDER) (practicalswift) 3a80944 Move LockAnnotation to make it reflect the truth (practicalswift) cc25885 Move LockAnnotation from threadsafety.h (imported code) to sync.h (our code) (practicalswift) Pull request description: `LockAnnotation lock(mutex);` is a guarantee to the compiler thread-analysis that `mutex` is locked (when it couldn't be determined otherwise). Before this PR it was possible to make the mistake of adding a `LockAnnotation` where the correct mutex is _not_ held. This in turn makes the thread-analysis reasoning being based on incorrect premises. This PR adds an assertion in the `LockAnnotation` ctor which checks that the guarantees given by us at compile-time are held also in practice (`ifdef DEBUG_LOCKORDER`). Issues like the one described in bitcoin#16028 will be discovered immediately with this PR merged. Changes in this PR: * Move `LockAnnotation` from `threadsafety.h` (imported code) to `sync.h` (our code) * Move `LockAnnotation` in `wallet_tests` to make it reflect the truth * Make sure the compile-time locking promises given via `LockAnnotation`:s hold also in practice at runtime (`ifdef DEBUG_LOCKORDER`) * Rename `LockAnnotation` to `LockAssertion` ACKs for commit 9f85e9: ryanofsky: utACK 9f85e9c. No changes at all since last review except clean rebase after base PR bitcoin#16033 was merged Tree-SHA512: fb80e78fe362adfd6ea8405bcb142c09b99f834fe8be4397282b223ca2c3a2bb9719a074a47a043b44757f840b239a6fcd2f98d14771f8729204834ecf608c3a
Fixes #16028.
Problem description:
LockAnnotation lock(::cs_main)is a guarantee to the compiler thread analysis that::cs_mainis locked (when it couldn't be determined otherwise).Despite being annotated with the locking guarantee ...
bitcoin/src/interfaces/chain.cpp
Lines 134 to 138 in 65526fc
...
getTipLocator()readschainActive(via::ChainActive()) without holdingcs_main.This can be verified by adding the following
AssertLockHeld(cs_main):