[starvation] Catch CountDownLatch.await calls on main thread

Reviewed By: ddino

Differential Revision: D7671323

fbshipit-source-id: 88fca56
master
Nikos Gorogiannis 7 years ago committed by Facebook Github Bot
parent f7ee0c2a2d
commit 7a9009e467

@ -203,7 +203,7 @@ let of_sil ~include_array_indexes ~f_resolve_id ~add_deref exp typ =
let is_null_literal = function Constant (Cint n) -> IntLit.isnull n | _ -> false let is_null_literal = function Constant (Cint n) -> IntLit.isnull n | _ -> false
let is_int_zero = function Constant Const.Cint i -> IntLit.iszero i | _ -> false let is_int_zero = function Constant (Const.Cint i) -> IntLit.iszero i | _ -> false
let rec eval_arithmetic_binop op e1 e2 = let rec eval_arithmetic_binop op e1 e2 =
match (eval e1, eval e2) with match (eval e1, eval e2) with

@ -20,6 +20,16 @@ let is_java_static pname =
false false
let is_countdownlatch_await pn =
match pn with
| Typ.Procname.Java java_pname ->
let classname = Typ.Procname.Java.get_class_name java_pname in
let mthd = Typ.Procname.Java.get_method java_pname in
String.equal classname "java.util.concurrent.CountDownLatch" && String.equal mthd "await"
| _ ->
false
(* an IBinder.transact call is an RPC. If the 4th argument (5th counting `this` as the first) (* 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 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. blocking. If the 4th argument is anything else, we assume a one-way call which doesn't block.
@ -95,8 +105,10 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| LockedIfTrue -> | LockedIfTrue ->
astate astate
| NoEffect -> | NoEffect ->
if is_two_way_binder_transact tenv actuals callee_pname then if
Domain.blocking_call callee_pname loc astate is_countdownlatch_await callee_pname
|| is_two_way_binder_transact tenv actuals callee_pname
then Domain.blocking_call callee_pname loc astate
else if is_on_main_thread callee_pname then Domain.set_on_main_thread astate else if is_on_main_thread callee_pname then Domain.set_on_main_thread astate
else else
Summary.read_summary pdesc callee_pname Summary.read_summary pdesc callee_pname

@ -0,0 +1,34 @@
/*
* Copyright (c) 2018 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
import java.util.concurrent.CountDownLatch;
import android.support.annotation.UiThread;
class Countdwn {
CountDownLatch latch;
void awaitOnMainByCallBad() throws InterruptedException {
OurThreadUtils.assertMainThread();
latch.await();
}
@UiThread
void awaitOnMainByAnnotBad() throws InterruptedException {
latch.await();
}
void countDownOk() throws InterruptedException {
OurThreadUtils.assertMainThread();
latch.countDown();
}
void awaitOnAnyThreadOk() throws InterruptedException {
latch.await();
}
}

@ -1,6 +1,8 @@
codetoanalyze/java/starvation/Binders.java, void Binders.annotationBad(), 0, STARVATION, ERROR, [Method start: void Binders.annotationBad(),Method call: void Binders.doTransact(),Calls boolean Binder.transact(int,Parcel,Parcel,int)] codetoanalyze/java/starvation/Binders.java, void Binders.annotationBad(), 0, STARVATION, ERROR, [Method start: void Binders.annotationBad(),Method call: void Binders.doTransact(),Calls boolean Binder.transact(int,Parcel,Parcel,int)]
codetoanalyze/java/starvation/Binders.java, void Binders.interBad(), 0, STARVATION, ERROR, [Method start: void Binders.interBad(),Calls boolean Binder.transact(int,Parcel,Parcel,int)] codetoanalyze/java/starvation/Binders.java, void Binders.interBad(), 0, STARVATION, ERROR, [Method start: void Binders.interBad(),Calls boolean Binder.transact(int,Parcel,Parcel,int)]
codetoanalyze/java/starvation/Binders.java, void Binders.intraBad(), 0, STARVATION, ERROR, [Method start: void Binders.intraBad(),Method call: void Binders.doTransact(),Calls boolean Binder.transact(int,Parcel,Parcel,int)] codetoanalyze/java/starvation/Binders.java, void Binders.intraBad(), 0, STARVATION, ERROR, [Method start: void Binders.intraBad(),Method call: void Binders.doTransact(),Calls boolean Binder.transact(int,Parcel,Parcel,int)]
codetoanalyze/java/starvation/Countdwn.java, void Countdwn.awaitOnMainByAnnotBad(), 0, STARVATION, ERROR, [Method start: void Countdwn.awaitOnMainByAnnotBad(),Calls void CountDownLatch.await()]
codetoanalyze/java/starvation/Countdwn.java, void Countdwn.awaitOnMainByCallBad(), 0, STARVATION, ERROR, [Method start: void Countdwn.awaitOnMainByCallBad(),Calls void CountDownLatch.await()]
codetoanalyze/java/starvation/InnerClass.java, void InnerClass$InnerClassA.innerOuterBad(), 0, STARVATION, ERROR, [[Trace 1] Locks this in class InnerClass$InnerClassA*,Method call: void InnerClass.bar(),Locks this in class InnerClass*,[Trace 2] Locks this in class InnerClass*,Method call: void InnerClass$InnerClassA.baz(),Locks this in class InnerClass$InnerClassA*] codetoanalyze/java/starvation/InnerClass.java, void InnerClass$InnerClassA.innerOuterBad(), 0, STARVATION, ERROR, [[Trace 1] Locks this in class InnerClass$InnerClassA*,Method call: void InnerClass.bar(),Locks this in class InnerClass*,[Trace 2] Locks this in class InnerClass*,Method call: void InnerClass$InnerClassA.baz(),Locks this in class InnerClass$InnerClassA*]
codetoanalyze/java/starvation/InnerClass.java, void InnerClass.outerInnerBad(InnerClass$InnerClassA), 0, STARVATION, ERROR, [[Trace 1] Locks this in class InnerClass*,Method call: void InnerClass$InnerClassA.baz(),Locks this in class InnerClass$InnerClassA*,[Trace 2] Method start: InnerClass$InnerClassA.<init>(InnerClass,Object),Locks this in class InnerClass$InnerClassA*,Method call: void InnerClass.bar(),Locks this in class InnerClass*] codetoanalyze/java/starvation/InnerClass.java, void InnerClass.outerInnerBad(InnerClass$InnerClassA), 0, STARVATION, ERROR, [[Trace 1] Locks this in class InnerClass*,Method call: void InnerClass$InnerClassA.baz(),Locks this in class InnerClass$InnerClassA*,[Trace 2] Method start: InnerClass$InnerClassA.<init>(InnerClass,Object),Locks this in class InnerClass$InnerClassA*,Method call: void InnerClass.bar(),Locks this in class InnerClass*]
codetoanalyze/java/starvation/Interclass.java, void InterclassA.interclass2Bad(Interclass), 0, STARVATION, ERROR, [[Trace 1] Locks this in class InterclassA*,Method call: void Interclass.interclass2Bad(),Locks this in class Interclass*,[Trace 2] Locks this in class Interclass*,Method call: void InterclassA.interclass1Bad(),Locks this in class InterclassA*] codetoanalyze/java/starvation/Interclass.java, void InterclassA.interclass2Bad(Interclass), 0, STARVATION, ERROR, [[Trace 1] Locks this in class InterclassA*,Method call: void Interclass.interclass2Bad(),Locks this in class Interclass*,[Trace 2] Locks this in class Interclass*,Method call: void InterclassA.interclass1Bad(),Locks this in class InterclassA*]

Loading…
Cancel
Save