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 Nicolas Palix, DIKU. GPLv2. 10// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 11// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 12// URL: http://coccinelle.lip6.fr/ 13// Comments: 14// Options: -no_includes -include_headers 15 16virtual org 17virtual report 18 19@prelocked@ 20position p1,p; 21expression E1; 22@@ 23 24( 25mutex_lock@p1 26| 27mutex_trylock@p1 28| 29spin_lock@p1 30| 31spin_trylock@p1 32| 33read_lock@p1 34| 35read_trylock@p1 36| 37write_lock@p1 38| 39write_trylock@p1 40| 41read_lock_irq@p1 42| 43write_lock_irq@p1 44| 45read_lock_irqsave@p1 46| 47write_lock_irqsave@p1 48| 49spin_lock_irq@p1 50| 51spin_lock_irqsave@p1 52) (E1@p,...); 53 54@looped@ 55position r; 56@@ 57 58for(...;...;...) { <+... return@r ...; ...+> } 59 60@err@ 61expression E1; 62position prelocked.p; 63position up != prelocked.p1; 64position r!=looped.r; 65identifier lock,unlock; 66@@ 67 68lock(E1@p,...); 69<+... when != E1 70if (...) { 71 ... when != E1 72 return@r ...; 73} 74...+> 75unlock@up(E1,...); 76 77@script:python depends on org@ 78p << prelocked.p1; 79lock << err.lock; 80unlock << err.unlock; 81p2 << err.r; 82@@ 83 84cocci.print_main(lock,p) 85cocci.print_secs(unlock,p2) 86 87@script:python depends on report@ 88p << prelocked.p1; 89lock << err.lock; 90unlock << err.unlock; 91p2 << err.r; 92@@ 93 94msg = "preceding lock on line %s" % (p[0].line) 95coccilib.report.print_report(p2[0],msg) 96