Skip to content

Commit 1df011c

Browse files
himanshujha199640nashif
authored andcommitted
coccinelle: Add script to find cases of missing locks
This script finds cases of missing locks in the code. There is some possibilty of false positives in cases where a particular function is supposed to exit with the lock held or there is any preceding function call that releases the lock. Suggested-by: Julia Lawall <[email protected]> Signed-off-by: Himanshu Jha <[email protected]>
1 parent 6f98ae3 commit 1df011c

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

scripts/coccinelle/mini_lock.cocci

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/// Find missing unlocks. This semantic match considers the specific case
2+
/// where the unlock is missing from an if branch, and there is a lock
3+
/// before the if and an unlock after the if. False positives are due to
4+
/// cases where the if branch represents a case where the function is
5+
/// supposed to exit with the lock held, or where there is some preceding
6+
/// function call that releases the lock.
7+
///
8+
// Confidence: Moderate
9+
// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
10+
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
11+
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
12+
// URL: http://coccinelle.lip6.fr/
13+
14+
virtual context
15+
virtual org
16+
virtual report
17+
18+
@prelocked depends on !(file in "ext")@
19+
position p1,p;
20+
expression E1;
21+
@@
22+
23+
(
24+
irq_lock@p1
25+
|
26+
k_mutex_lock@p1
27+
|
28+
k_sem_take@p1
29+
|
30+
k_spin_lock@p1
31+
) (E1@p,...);
32+
33+
@looped depends on !(file in "ext")@
34+
position r;
35+
@@
36+
37+
for(...;...;...) { <+... return@r ...; ...+> }
38+
39+
@balanced exists@
40+
position p1 != prelocked.p1;
41+
position prelocked.p;
42+
position pif;
43+
identifier lock,unlock;
44+
expression x <= prelocked.E1;
45+
expression E,prelocked.E1;
46+
expression E2;
47+
@@
48+
49+
if (E) {
50+
... when != E1
51+
lock(E1@p,...)
52+
... when any
53+
}
54+
... when != E1
55+
when != \(x = E2\|&x\)
56+
if@pif (E) {
57+
... when != E1
58+
unlock@p1(E1,...)
59+
... when any
60+
}
61+
62+
@err depends on !(file in "ext") exists@
63+
expression E1;
64+
position prelocked.p,balanced.pif;
65+
position up != prelocked.p1;
66+
position r!=looped.r;
67+
identifier lock,unlock;
68+
statement S1,S2;
69+
@@
70+
71+
*lock(E1@p,...);
72+
... when != E1
73+
when any
74+
when != if@pif (...) S1
75+
if (...) {
76+
... when != E1
77+
when != if@pif (...) S2
78+
* return@r ...;
79+
}
80+
... when != E1
81+
when any
82+
*unlock@up(E1,...);
83+
84+
@script:python depends on org@
85+
p << prelocked.p1;
86+
lock << err.lock;
87+
unlock << err.unlock;
88+
p2 << err.r;
89+
@@
90+
91+
cocci.print_main(lock,p)
92+
cocci.print_secs(unlock,p2)
93+
94+
@script:python depends on report@
95+
p << prelocked.p1;
96+
lock << err.lock;
97+
unlock << err.unlock;
98+
p2 << err.r;
99+
@@
100+
101+
msg = "preceding lock on line %s" % (p[0].line)
102+
coccilib.report.print_report(p2[0],msg)

0 commit comments

Comments
 (0)