-
Notifications
You must be signed in to change notification settings - Fork 88
HB-relationship involving thread creations while mutexes are held #1913
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements the second part of happens-before (HB) relationship analysis for thread creations while mutexes are held. It introduces two new analyses (MustlockHistory and DescendantLockset) that work together to detect race conditions by establishing happens-before relationships between thread operations based on mutex locking patterns.
Changes:
- Added
MustlockHistoryanalysis to track which threads have locked specific mutexes - Added
DescendantLocksetanalysis to compute descendant locksets and determine happens-before relationships - Extended
CreationLocksetanalysis with query support for integration with the new analyses - Added 20 comprehensive test cases covering both race-free and racing scenarios
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
src/analyses/mustlockHistory.ml |
New analysis tracking mutex lock history per thread |
src/analyses/descendantLockset.ml |
New analysis computing descendant locksets and HB relationships |
src/analyses/creationLockset.ml |
Added CreationLockset query support |
src/domains/queries.ml |
Added CreationLockset and MustlockHistory query types with supporting domains |
src/goblint_lib.ml |
Exported the two new analysis modules |
tests/regression/53-races-mhp/40-45-*.c |
Race-free test cases validating correct HB detection |
tests/regression/53-races-mhp/50-59-*.c |
Racing test cases validating race detection |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
tests/regression/53-races-mhp/45-dl_multiple_mutexes_racefree.c
Outdated
Show resolved
Hide resolved
… of descendant lockset analysis
|
Random thought: What do your analyses do for recursive mutexes? Are they sound in these cases? |
|
Thanks for bringing this up, those would never have crossed my mind. I think the analyses remain sound, but get less precise. The only relevant thing changing here coming to my mind is the fact that after an unlock, we can't assume anymore that the mutex is now unlocked. As unlock statements have been places in our analyses, where we assume things to just break, but not start/keep working, this wouldn't be an issue. |
👍 Could you add tests here and maybe also include some tests for your first analysis (potentially in a separate PR)? |
58a1714 to
ee18c9a
Compare
|
@DrMichaelPetter and I decided to remove the flow-insensitive analysis detecting cases like the third example, since we did not see a simple way of both having only monotonic contributions and being certain that the analysis is sound |
|
Just so I can understand: why is monotonicity important here? @dabund24 @DrMichaelPetter (By default (without update rule) globals are accumulated, so their values grow monotonically anyway) |
|
I'm not deeply familiar with what exactly you're trying to do, but in general our fixpoint solvers can deal with non-monotonic right-hand sides without any issues. ==== Nothing wrong with copying values from a MapBot to a MapTop, though it usually doesn't do much for globals. If the binding is not present, it is assumed to be top, so contributing more to it will not really have much of an effect... |
|
Thanks for remarking this. In that case, I'm going to undo the changes |
|
No, please discuss with @DrMichaelPetter what he suggests before doing so. |

second part of #1805. The first half was implemented in #1865.
closes #1805.
Summary
Simplest case: After creating$t_1$ in $t_0$ with mutex $l$ held, succeeding statements until maybe unlocking in $t_0$ must happen before everything after definitely locking $l$ in $t_1$ .
generalizations:
Examples
In the following examples,
Amust happen beforeB.Simple example
graph TB; subgraph t1; E["lock(l);"]-->F; F["unlock(l);"]-->G; G((B)) end; subgraph t0; A["lock(l);"]-->B; B["create(t1);"]-->C; C((A))-->D; D["unlock(l);"]; end; B-.->EBin a descendant ofgraph TB; subgraph t2; H((B)) end; subgraph t1; E["lock(l);"]-->F; F["create(t2);"] end; subgraph t0; A["lock(l);"]-->B; B["create(t1);"]-->C; C((A))-->D; D["unlock(l);"]; end; B-.->E F-.->HAin a descendant ofNote
This case is not covered by the analysis implemented in this Pull Request, but may be added some time later
graph TB; subgraph t1; E["lock(l);"]-->I; I["unlock(l);"]-->F; F((B)); end; subgraph t2; H((A)) end; subgraph t0; A["lock(l);"]-->B; B["create(t1);"]-->C; C["create(t2);"]-->D; D["join(t2);"]-->G; G["unlock(l);"] end; B-.->E C-.->H H-.->DHere, it is important that no unlock happens in$t_0$ before $t_2$ is joined into $t_0$ , which was computed in #1865.
Dependency Analyses
Analyses
Descendant Locksets$\mathcal{DL}$
MapBotTransfer functions
Mustlock History$\mathcal{LH}$
MapTopTransfer functions
Happens-Before rules
Statement$\mathcal{LH}_ 2, \mathcal T_2$ must happen after $\mathcal{DL}_ 1, \mathcal{LH}_ 1, \mathcal T_1$ , if:
$\exists \mathcal T_2\mapsto L_a\in\mathcal{DL}_ 1, l_ {LH}\mapsto T_ {LH}\in \mathcal{LH}_ 1, t_ {LH}\in T_ {LH}:$
$l_{LH}\in L_a\land\mathcal T_1\in \mathcal A\ t_{LH}\land(t_{LH}\in\mathcal A\ \mathcal T_2\lor t_{LH}=\mathcal T_2)$
s2withs1with