diff --git a/infer/src/concurrency/StarvationModels.ml b/infer/src/concurrency/StarvationModels.ml index b90c0c8c8..11f2ce8dd 100644 --- a/infer/src/concurrency/StarvationModels.ml +++ b/infer/src/concurrency/StarvationModels.ml @@ -137,14 +137,19 @@ let may_block = let may_do_ipc = MethodMatcher.( - of_record - (* an IBinder.transact call is an RPC. If the 4th argument (5th counting `this` as the first) - is int-zero then a reply is expected and returned from the remote process, thus potentially - blocking. If the 4th argument is anything else, we assume a one-way call which doesn't block. *) - { default with - classname= "android.os.IBinder" - ; methods= ["transact"] - ; actuals_pred= (fun actuals -> List.nth actuals 4 |> Option.exists ~f:HilExp.is_int_zero) }) + of_records + [ (* an IBinder.transact call is an RPC. If the 4th argument (5th counting `this` as the first) + is int-zero then a reply is expected and returned from the remote process, thus potentially + blocking. If the 4th argument is anything else, we assume a one-way call which doesn't block. *) + { default with + classname= "android.os.IBinder" + ; methods= ["transact"] + ; actuals_pred= (fun actuals -> List.nth actuals 4 |> Option.exists ~f:HilExp.is_int_zero) + } + ; (* indirectly makes a transact call*) + { default with + classname= "android.net.ConnectivityManager" + ; methods= ["getActiveNetworkInfo"] } ]) let is_monitor_wait = diff --git a/infer/tests/codetoanalyze/java/starvation/Binders.java b/infer/tests/codetoanalyze/java/starvation/Binders.java index dbf5158a2..1bd9411b6 100644 --- a/infer/tests/codetoanalyze/java/starvation/Binders.java +++ b/infer/tests/codetoanalyze/java/starvation/Binders.java @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import android.net.ConnectivityManager; import android.os.Binder; import android.os.RemoteException; import android.support.annotation.UiThread; @@ -57,4 +58,9 @@ class Binders { void forceMainThread() { OurThreadUtils.assertMainThread(); } + + @UiThread + void getActiveNetworkInfoBad(ConnectivityManager c) { + c.getActiveNetworkInfo(); + } } diff --git a/infer/tests/codetoanalyze/java/starvation/issues.exp b/infer/tests/codetoanalyze/java/starvation/issues.exp index ec4d64026..c1d410242 100644 --- a/infer/tests/codetoanalyze/java/starvation/issues.exp +++ b/infer/tests/codetoanalyze/java/starvation/issues.exp @@ -1,8 +1,9 @@ codetoanalyze/java/starvation/AsyncTaskGet.java, AsyncTaskGet.lockOnUiThreadBad():void, 31, STARVATION, no_bucket, ERROR, [[Trace 1] `void AsyncTaskGet.lockOnUiThreadBad()`, locks `this.lock` in `class AsyncTaskGet`,[Trace 2] `void AsyncTaskGet.taskGetUnderLock()`, locks `this.lock` in `class AsyncTaskGet`,calls `Object AsyncTask.get()`] codetoanalyze/java/starvation/AsyncTaskGet.java, AsyncTaskGet.taskGetOnUiThreadBad():void, 20, STARVATION, no_bucket, ERROR, [`void AsyncTaskGet.taskGetOnUiThreadBad()`,calls `Object AsyncTask.get()`] -codetoanalyze/java/starvation/Binders.java, Binders.annotationBad():void, 41, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void Binders.annotationBad()`,Method call: `void Binders.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation/Binders.java, Binders.interBad():void, 31, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void Binders.interBad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation/Binders.java, Binders.intraBad():void, 36, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void Binders.intraBad()`,Method call: `void Binders.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/Binders.java, Binders.annotationBad():void, 42, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void Binders.annotationBad()`,Method call: `void Binders.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/Binders.java, Binders.getActiveNetworkInfoBad(android.net.ConnectivityManager):void, 64, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void Binders.getActiveNetworkInfoBad(ConnectivityManager)`,calls `NetworkInfo ConnectivityManager.getActiveNetworkInfo()`] +codetoanalyze/java/starvation/Binders.java, Binders.interBad():void, 32, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void Binders.interBad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/Binders.java, Binders.intraBad():void, 37, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void Binders.intraBad()`,Method call: `void Binders.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation/Countdwn.java, Countdwn.awaitOnMainByAnnotBad():void, 21, STARVATION, no_bucket, ERROR, [`void Countdwn.awaitOnMainByAnnotBad()`,calls `void CountDownLatch.await()`] codetoanalyze/java/starvation/Countdwn.java, Countdwn.awaitOnMainByCallBad():void, 16, STARVATION, no_bucket, ERROR, [`void Countdwn.awaitOnMainByCallBad()`,calls `void CountDownLatch.await()`] codetoanalyze/java/starvation/FutureGet.java, FutureGet.getDirectBad():void, 21, STARVATION, no_bucket, ERROR, [`void FutureGet.getDirectBad()`,calls `Object Future.get()`]