Repository navigation
[DRAFT] [starvation] match locks reached through members with the locks of their class - #2205
Closed
VladimirMakaev wants to merge 2 commits into
Closed
VladimirMakaev wants to merge 2 commits into
VladimirMakaev wants to merge 2 commits into
Conversation
…only in qualifiers
The clang frontend types `this` as `C const *` in the const methods of `C` and as `C *` elsewhere.
RacerD and Starvation compared these types with their qualifiers when pairing accesses or locks of
two methods, missing races and deadlocks involving const methods:
```cpp
#include <mutex>
class C {
std::mutex m_;
int x_;
public:
int get() const { return x_; } // Infer missed: LOCK_CONSISTENCY_VIOLATION
void set(int v) {
std::lock_guard<std::mutex> l(m_);
x_ = v;
}
};
```
RacerD now ignores the base type when grouping accesses, as `AccessPath.compare` does. Starvation
compares the root types of parameter-rooted locks across threads modulo qualifiers, so `const C *`
parameters also pair with `C *` ones.
Trade-off: two-instance deadlocks with const on one side only, such as `x.copy_from(&y)` against
`y.copy_to(&x)`, are no longer reported, like the same code without const.
## Test plan
New tests `cpp/racerd/const_methods.cpp` and `cpp/starvation/const_methods.cpp`. Of their `_bad`
cases, main reports only the two-instance deadlock `FN_copy_from_bad`, which is no longer
reported. All codetoanalyze tests pass.
…eir class
Starvation matched locks across threads only with equal root types and accesses, and searched for
the other thread only in the root class of a lock, so `Client`'s `this->owner->first` never matched
`Owner`'s `this->first`:
```cpp
#include <mutex>
struct Owner {
std::mutex first, second;
void lock_first_then_second() { std::lock_guard<std::mutex> l1(first), l2(second); }
};
struct Client {
Owner* owner;
void lock_second_then_first() {
std::lock_guard<std::mutex> l1(owner->second), l2(owner->first); // Infer missed: DEADLOCK
}
};
```
An object reached through fields may now be the root of another thread's lock, unless an earlier
object on the path has its class (as in a list), and every class on the lock paths is searched,
also in Java and for C structs in whole-program mode. Deduplication keeps deadlocks that only one
side finds. A thread in `wait()` blocks the UI thread only if another lock it holds may be the UI
thread's.
Limitations: gate locks reached through members count as common, as for parameters; starvation is
searched only from the UI thread, which does not match its `this->m` with another class's
`this->owner->m`.
## Test plan
New tests in `member_locks.cpp`, `member_locks.c`, `MemberLocks.java` and `ObjWait.java`, and new
`cpp/starvation-dedup` and `c/starvation-dedup` directories. Main reports only the `TreeNode`
deadlocks, `FN_gate_then_ba_bad` and `ObjWaitHoldsOtherParam`, and falsely `ObjWaitOnOnlyLock`.
`Parameters.oneWaySyncOnParamBad` now reports the other side of its deadlock. All codetoanalyze
tests pass.
VladimirMakaev
force-pushed
the
starvation-member-locks
branch
2 times, most recently
from
October 5, 2026 06:55
6fc91de to
8116f88
Compare
VladimirMakaev
force-pushed
the
starvation-member-locks
branch
from
October 7, 2026 15:56
8116f88 to
60c0c16
Compare
Contributor
Author
|
Will reopen once current PR queue is cleared |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack: #2167 → #2205 (review only the top commit; lands after #2167)
Starvation matched locks across threads only with equal root types and accesses, and searched for
the other thread only in the root class of a lock, so
Client'sthis->owner->firstnever matchedOwner'sthis->first:An object reached through fields may now be the root of another thread's lock, unless an earlier
object on the path has its class (as in a list), and every class on the lock paths is searched,
also in Java and for C structs in whole-program mode. Deduplication keeps deadlocks that only one
side finds. A thread in
wait()blocks the UI thread only if another lock it holds may be the UIthread's.
Limitations: gate locks reached through members count as common, as for parameters; starvation is
searched only from the UI thread, which does not match its
this->mwith another class'sthis->owner->m.Test plan
New tests in
member_locks.cpp,member_locks.c,MemberLocks.javaandObjWait.java, and newcpp/starvation-dedupandc/starvation-dedupdirectories. Main reports only theTreeNodedeadlocks,
FN_gate_then_ba_badandObjWaitHoldsOtherParam, and falselyObjWaitOnOnlyLock.Parameters.oneWaySyncOnParamBadnow reports the other side of its deadlock. All codetoanalyzetests pass.