1*53ee8cc1Swenshuai.xi/// Find missing unlocks. This semantic match considers the specific case 2*53ee8cc1Swenshuai.xi/// where the unlock is missing from an if branch, and there is a lock 3*53ee8cc1Swenshuai.xi/// before the if and an unlock after the if. False positives are due to 4*53ee8cc1Swenshuai.xi/// cases where the if branch represents a case where the function is 5*53ee8cc1Swenshuai.xi/// supposed to exit with the lock held, or where there is some preceding 6*53ee8cc1Swenshuai.xi/// function call that releases the lock. 7*53ee8cc1Swenshuai.xi/// 8*53ee8cc1Swenshuai.xi// Confidence: Moderate 9*53ee8cc1Swenshuai.xi// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 10*53ee8cc1Swenshuai.xi// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 11*53ee8cc1Swenshuai.xi// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 12*53ee8cc1Swenshuai.xi// URL: http://coccinelle.lip6.fr/ 13*53ee8cc1Swenshuai.xi// Comments: 14*53ee8cc1Swenshuai.xi// Options: -no_includes -include_headers 15*53ee8cc1Swenshuai.xi 16*53ee8cc1Swenshuai.xivirtual org 17*53ee8cc1Swenshuai.xivirtual report 18*53ee8cc1Swenshuai.xi 19*53ee8cc1Swenshuai.xi@prelocked@ 20*53ee8cc1Swenshuai.xiposition p1,p; 21*53ee8cc1Swenshuai.xiexpression E1; 22*53ee8cc1Swenshuai.xi@@ 23*53ee8cc1Swenshuai.xi 24*53ee8cc1Swenshuai.xi( 25*53ee8cc1Swenshuai.ximutex_lock@p1 26*53ee8cc1Swenshuai.xi| 27*53ee8cc1Swenshuai.ximutex_trylock@p1 28*53ee8cc1Swenshuai.xi| 29*53ee8cc1Swenshuai.xispin_lock@p1 30*53ee8cc1Swenshuai.xi| 31*53ee8cc1Swenshuai.xispin_trylock@p1 32*53ee8cc1Swenshuai.xi| 33*53ee8cc1Swenshuai.xiread_lock@p1 34*53ee8cc1Swenshuai.xi| 35*53ee8cc1Swenshuai.xiread_trylock@p1 36*53ee8cc1Swenshuai.xi| 37*53ee8cc1Swenshuai.xiwrite_lock@p1 38*53ee8cc1Swenshuai.xi| 39*53ee8cc1Swenshuai.xiwrite_trylock@p1 40*53ee8cc1Swenshuai.xi| 41*53ee8cc1Swenshuai.xiread_lock_irq@p1 42*53ee8cc1Swenshuai.xi| 43*53ee8cc1Swenshuai.xiwrite_lock_irq@p1 44*53ee8cc1Swenshuai.xi| 45*53ee8cc1Swenshuai.xiread_lock_irqsave@p1 46*53ee8cc1Swenshuai.xi| 47*53ee8cc1Swenshuai.xiwrite_lock_irqsave@p1 48*53ee8cc1Swenshuai.xi| 49*53ee8cc1Swenshuai.xispin_lock_irq@p1 50*53ee8cc1Swenshuai.xi| 51*53ee8cc1Swenshuai.xispin_lock_irqsave@p1 52*53ee8cc1Swenshuai.xi) (E1@p,...); 53*53ee8cc1Swenshuai.xi 54*53ee8cc1Swenshuai.xi@looped@ 55*53ee8cc1Swenshuai.xiposition r; 56*53ee8cc1Swenshuai.xi@@ 57*53ee8cc1Swenshuai.xi 58*53ee8cc1Swenshuai.xifor(...;...;...) { <+... return@r ...; ...+> } 59*53ee8cc1Swenshuai.xi 60*53ee8cc1Swenshuai.xi@err@ 61*53ee8cc1Swenshuai.xiexpression E1; 62*53ee8cc1Swenshuai.xiposition prelocked.p; 63*53ee8cc1Swenshuai.xiposition up != prelocked.p1; 64*53ee8cc1Swenshuai.xiposition r!=looped.r; 65*53ee8cc1Swenshuai.xiidentifier lock,unlock; 66*53ee8cc1Swenshuai.xi@@ 67*53ee8cc1Swenshuai.xi 68*53ee8cc1Swenshuai.xilock(E1@p,...); 69*53ee8cc1Swenshuai.xi<+... when != E1 70*53ee8cc1Swenshuai.xiif (...) { 71*53ee8cc1Swenshuai.xi ... when != E1 72*53ee8cc1Swenshuai.xi return@r ...; 73*53ee8cc1Swenshuai.xi} 74*53ee8cc1Swenshuai.xi...+> 75*53ee8cc1Swenshuai.xiunlock@up(E1,...); 76*53ee8cc1Swenshuai.xi 77*53ee8cc1Swenshuai.xi@script:python depends on org@ 78*53ee8cc1Swenshuai.xip << prelocked.p1; 79*53ee8cc1Swenshuai.xilock << err.lock; 80*53ee8cc1Swenshuai.xiunlock << err.unlock; 81*53ee8cc1Swenshuai.xip2 << err.r; 82*53ee8cc1Swenshuai.xi@@ 83*53ee8cc1Swenshuai.xi 84*53ee8cc1Swenshuai.xicocci.print_main(lock,p) 85*53ee8cc1Swenshuai.xicocci.print_secs(unlock,p2) 86*53ee8cc1Swenshuai.xi 87*53ee8cc1Swenshuai.xi@script:python depends on report@ 88*53ee8cc1Swenshuai.xip << prelocked.p1; 89*53ee8cc1Swenshuai.xilock << err.lock; 90*53ee8cc1Swenshuai.xiunlock << err.unlock; 91*53ee8cc1Swenshuai.xip2 << err.r; 92*53ee8cc1Swenshuai.xi@@ 93*53ee8cc1Swenshuai.xi 94*53ee8cc1Swenshuai.ximsg = "preceding lock on line %s" % (p[0].line) 95*53ee8cc1Swenshuai.xicoccilib.report.print_report(p2[0],msg) 96