[starvation] add test for master-lock false positive

Summary: Holding a master lock and then acquiring two other locks inside can generate a false positive as shown.

Reviewed By: mityal

Differential Revision: D17710076

fbshipit-source-id: 5bc910ba2
master
Nikos Gorogiannis 5 years ago committed by Facebook Github Bot
parent f57bb9be0a
commit fb77efea6a

@ -0,0 +1,49 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class MasterLock {
Object a, b;
// classic deadlock between 2 methods
// 1st method has a and wants b
void oneWayBad() {
synchronized (a) {
synchronized (b) {
}
}
}
// 2nd method has b and wants a
void theOtherWayBad() {
synchronized (b) {
synchronized (a) {
}
}
}
Object master, x, y;
// both methods hold the master lock so cannot interleave
// and thus cannot deadlock
void FP_oneWayOk() {
synchronized (master) {
synchronized (x) {
synchronized (y) {
}
}
}
}
void FP_theOtherWayOk() {
synchronized (master) {
synchronized (y) {
synchronized (x) {
}
}
}
}
}

@ -25,6 +25,10 @@ codetoanalyze/java/starvation/LocklessTests.java, LocklessTestsB.locklessMethod(
codetoanalyze/java/starvation/LocklessTests.java, LocklessTestsC.locklessMethod():void, 52, LOCKLESS_VIOLATION, no_bucket, ERROR, [`void LocklessTestsC.locklessMethod()`,Method call: `void LocklessTestsC.takeLock()`, locks `this` in `class LocklessTestsC`] codetoanalyze/java/starvation/LocklessTests.java, LocklessTestsC.locklessMethod():void, 52, LOCKLESS_VIOLATION, no_bucket, ERROR, [`void LocklessTestsC.locklessMethod()`,Method call: `void LocklessTestsC.takeLock()`, locks `this` in `class LocklessTestsC`]
codetoanalyze/java/starvation/MainThreadTest.java, AnnotatedClass.callTransactBad(MainThreadTest):void, 30, STARVATION, no_bucket, ERROR, [`void AnnotatedClass.callTransactBad(MainThreadTest)`,Method call: `void MainThreadTest.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`,[Trace on UI thread] `void AnnotatedClass.callTransactBad(MainThreadTest)`,class `AnnotatedClass` is annotated `UiThread`] codetoanalyze/java/starvation/MainThreadTest.java, AnnotatedClass.callTransactBad(MainThreadTest):void, 30, STARVATION, no_bucket, ERROR, [`void AnnotatedClass.callTransactBad(MainThreadTest)`,Method call: `void MainThreadTest.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`,[Trace on UI thread] `void AnnotatedClass.callTransactBad(MainThreadTest)`,class `AnnotatedClass` is annotated `UiThread`]
codetoanalyze/java/starvation/MainThreadTest.java, MainThreadTest.callTransactBad():void, 23, STARVATION, no_bucket, ERROR, [`void MainThreadTest.callTransactBad()`,Method call: `void MainThreadTest.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`,[Trace on UI thread] `void MainThreadTest.callTransactBad()`,`void MainThreadTest.callTransactBad()` is annotated `UiThread`] codetoanalyze/java/starvation/MainThreadTest.java, MainThreadTest.callTransactBad():void, 23, STARVATION, no_bucket, ERROR, [`void MainThreadTest.callTransactBad()`,Method call: `void MainThreadTest.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`,[Trace on UI thread] `void MainThreadTest.callTransactBad()`,`void MainThreadTest.callTransactBad()` is annotated `UiThread`]
codetoanalyze/java/starvation/MasterLock.java, MasterLock.FP_oneWayOk():void, 34, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MasterLock.FP_oneWayOk()`, locks `this.x` in `class MasterLock`, locks `this.y` in `class MasterLock`,[Trace 2] `void MasterLock.FP_theOtherWayOk()`, locks `this.y` in `class MasterLock`, locks `this.x` in `class MasterLock`]
codetoanalyze/java/starvation/MasterLock.java, MasterLock.FP_theOtherWayOk():void, 43, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MasterLock.FP_theOtherWayOk()`, locks `this.y` in `class MasterLock`, locks `this.x` in `class MasterLock`,[Trace 2] `void MasterLock.FP_oneWayOk()`, locks `this.x` in `class MasterLock`, locks `this.y` in `class MasterLock`]
codetoanalyze/java/starvation/MasterLock.java, MasterLock.oneWayBad():void, 14, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MasterLock.oneWayBad()`, locks `this.a` in `class MasterLock`, locks `this.b` in `class MasterLock`,[Trace 2] `void MasterLock.theOtherWayBad()`, locks `this.b` in `class MasterLock`, locks `this.a` in `class MasterLock`]
codetoanalyze/java/starvation/MasterLock.java, MasterLock.theOtherWayBad():void, 22, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MasterLock.theOtherWayBad()`, locks `this.b` in `class MasterLock`, locks `this.a` in `class MasterLock`,[Trace 2] `void MasterLock.oneWayBad()`, locks `this.a` in `class MasterLock`, locks `this.b` in `class MasterLock`]
codetoanalyze/java/starvation/MyActivity.java, MyActivity.onCreate(android.os.Bundle):void, 28, STARVATION, no_bucket, ERROR, [`void MyActivity.onCreate(Bundle)`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`,[Trace on UI thread] `void MyActivity.onCreate(Bundle)`,`void MyActivity.onCreate(Bundle)` is a standard UI-thread method] codetoanalyze/java/starvation/MyActivity.java, MyActivity.onCreate(android.os.Bundle):void, 28, STARVATION, no_bucket, ERROR, [`void MyActivity.onCreate(Bundle)`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`,[Trace on UI thread] `void MyActivity.onCreate(Bundle)`,`void MyActivity.onCreate(Bundle)` is a standard UI-thread method]
codetoanalyze/java/starvation/MyActivity.java, MyActivity.onDestroy():void, 58, STARVATION, no_bucket, ERROR, [`void MyActivity.onDestroy()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`,[Trace on UI thread] `void MyActivity.onDestroy()`,`void MyActivity.onDestroy()` is a standard UI-thread method] codetoanalyze/java/starvation/MyActivity.java, MyActivity.onDestroy():void, 58, STARVATION, no_bucket, ERROR, [`void MyActivity.onDestroy()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`,[Trace on UI thread] `void MyActivity.onDestroy()`,`void MyActivity.onDestroy()` is a standard UI-thread method]
codetoanalyze/java/starvation/MyActivity.java, MyActivity.onPause():void, 48, STARVATION, no_bucket, ERROR, [`void MyActivity.onPause()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`,[Trace on UI thread] `void MyActivity.onPause()`,`void MyActivity.onPause()` is a standard UI-thread method] codetoanalyze/java/starvation/MyActivity.java, MyActivity.onPause():void, 48, STARVATION, no_bucket, ERROR, [`void MyActivity.onPause()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`,[Trace on UI thread] `void MyActivity.onPause()`,`void MyActivity.onPause()` is a standard UI-thread method]

Loading…
Cancel
Save