[starvation-whole-program] more executor models

Summary: As per summary.

Reviewed By: artempyanykh

Differential Revision: D18591382

fbshipit-source-id: 3ce37d00b
master
Nikos Gorogiannis 5 years ago committed by Facebook Github Bot
parent cf6e881822
commit 883044763e

@ -212,6 +212,17 @@ let schedules_work =
fun tenv pname -> matcher tenv pname [] fun tenv pname -> matcher tenv pname []
let schedules_work_on_ui_thread =
let open MethodMatcher in
let matcher =
[ { default with
classname= "java.lang.Object"
; methods= ["postOnUiThread"; "runOnUiThread"; "postOnUiThreadDelayed"] } ]
|> of_records
in
fun tenv pname -> matcher tenv pname []
type executor_thread_constraint = ForUIThread | ForNonUIThread [@@deriving equal] type executor_thread_constraint = ForUIThread | ForNonUIThread [@@deriving equal]
(* Executors are usually stored in fields and annotated according to what type of thread (* Executors are usually stored in fields and annotated according to what type of thread

@ -52,3 +52,6 @@ val get_executor_effect :
-> HilExp.t list -> HilExp.t list
-> executor_thread_constraint option -> executor_thread_constraint option
(** does the function return an executor and of which thread? *) (** does the function return an executor and of which thread? *)
val schedules_work_on_ui_thread : Tenv.t -> Typ.Procname.t -> bool
(** method call known to directly schedule work on UI thread *)

@ -102,6 +102,9 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
lazy (Domain.AttributeDomain.get_executor_constraint executor astate.attributes) ] lazy (Domain.AttributeDomain.get_executor_constraint executor astate.attributes) ]
in in
Option.fold thread_opt ~init:astate ~f:(schedule_work runnable) Option.fold thread_opt ~init:astate ~f:(schedule_work runnable)
| HilExp.AccessExpression runnable :: _
when StarvationModels.schedules_work_on_ui_thread tenv callee ->
schedule_work runnable astate StarvationModels.ForUIThread
| _ -> | _ ->
astate astate

@ -41,6 +41,40 @@ class ModeledExecutors {
} }
}); });
} }
// starvation via posting a transaction on UI thread
public void staticPostBlockingCallToUIThreadBad() {
Executors.postOnUiThread(
new Runnable() {
@Override
public void run() {
doTransact();
}
});
}
// starvation via running a transaction on UI thread
public void staticRunBlockingCallToUIThreadBad() {
Executors.runOnUiThread(
new Runnable() {
@Override
public void run() {
doTransact();
}
});
}
// starvation via running a delayed transaction on UI thread
public void staticPostDelayedBlockingCallToUIThreadBad() {
Executors.postOnUiThreadDelayed(
new Runnable() {
@Override
public void run() {
doTransact();
}
},
1000L);
}
} }
// modeled executors // modeled executors
@ -56,4 +90,10 @@ class Executors {
static Executor getBackgroundExecutor() { static Executor getBackgroundExecutor() {
return bgExecutor; return bgExecutor;
} }
public static void postOnUiThread(Runnable runnable) {}
public static void runOnUiThread(Runnable runnable) {}
public static void postOnUiThreadDelayed(Runnable runnable, long delayMs) {}
} }

@ -5,6 +5,9 @@ codetoanalyze/java/starvation-whole-program/Deadlock.java, Deadlock.postOnBGThre
codetoanalyze/java/starvation-whole-program/DirectStarvation.java, DirectStarvation.postBlockingCallToUIThreadBad():void, 29, STARVATION, no_bucket, ERROR, [`void DirectStarvation.postBlockingCallToUIThreadBad()`,Method call: `void DirectStarvation$1.run()`,Method call: `void DirectStarvation.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/DirectStarvation.java, DirectStarvation.postBlockingCallToUIThreadBad():void, 29, STARVATION, no_bucket, ERROR, [`void DirectStarvation.postBlockingCallToUIThreadBad()`,Method call: `void DirectStarvation$1.run()`,Method call: `void DirectStarvation.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]
codetoanalyze/java/starvation-whole-program/IndirectStarvation.java, IndirectStarvation.postBlockingCallToBackgroundThreadAndLockBad():void, 32, STARVATION, no_bucket, ERROR, [[Trace 1] `void IndirectStarvation.postBlockingCallToBackgroundThreadAndLockBad()`,Method call: `void IndirectStarvation$1.run()`, locks `this.monitorA` in `class IndirectStarvation`,[Trace 2] `void IndirectStarvation.postBlockingCallToBackgroundThreadAndLockBad()`,Method call: `void IndirectStarvation$2.run()`, locks `this.monitorA` in `class IndirectStarvation`,Method call: `void IndirectStarvation.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/IndirectStarvation.java, IndirectStarvation.postBlockingCallToBackgroundThreadAndLockBad():void, 32, STARVATION, no_bucket, ERROR, [[Trace 1] `void IndirectStarvation.postBlockingCallToBackgroundThreadAndLockBad()`,Method call: `void IndirectStarvation$1.run()`, locks `this.monitorA` in `class IndirectStarvation`,[Trace 2] `void IndirectStarvation.postBlockingCallToBackgroundThreadAndLockBad()`,Method call: `void IndirectStarvation$2.run()`, locks `this.monitorA` in `class IndirectStarvation`,Method call: `void IndirectStarvation.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]
codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.postBlockingCallToUIThreadBad():void, 25, STARVATION, no_bucket, ERROR, [`void ModeledExecutors.postBlockingCallToUIThreadBad()`,Method call: `void ModeledExecutors$1.run()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.postBlockingCallToUIThreadBad():void, 25, STARVATION, no_bucket, ERROR, [`void ModeledExecutors.postBlockingCallToUIThreadBad()`,Method call: `void ModeledExecutors$1.run()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]
codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.staticPostBlockingCallToUIThreadBad():void, 47, STARVATION, no_bucket, ERROR, [`void ModeledExecutors.staticPostBlockingCallToUIThreadBad()`,Method call: `void ModeledExecutors$3.run()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]
codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.staticPostDelayedBlockingCallToUIThreadBad():void, 69, STARVATION, no_bucket, ERROR, [`void ModeledExecutors.staticPostDelayedBlockingCallToUIThreadBad()`,Method call: `void ModeledExecutors$5.run()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]
codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.staticRunBlockingCallToUIThreadBad():void, 58, STARVATION, no_bucket, ERROR, [`void ModeledExecutors.staticRunBlockingCallToUIThreadBad()`,Method call: `void ModeledExecutors$4.run()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]
codetoanalyze/java/starvation-whole-program/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)`] codetoanalyze/java/starvation-whole-program/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)`]
codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onDestroy():void, 68, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MyActivity.onDestroy()`, locks `this.monitorC` in `class MyActivity`, locks `this.monitorB` in `class MyActivity`,[Trace 2] `void MyActivity.onPause()`,Method call: `void MyActivity$2.run()`, locks `this.monitorB` in `class MyActivity`, locks `this.monitorC` in `class MyActivity`] codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onDestroy():void, 68, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MyActivity.onDestroy()`, locks `this.monitorC` in `class MyActivity`, locks `this.monitorB` in `class MyActivity`,[Trace 2] `void MyActivity.onPause()`,Method call: `void MyActivity$2.run()`, locks `this.monitorB` in `class MyActivity`, locks `this.monitorC` in `class MyActivity`]
codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onPause():void, 76, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MyActivity.onPause()`,Method call: `void MyActivity$2.run()`, locks `this.monitorB` in `class MyActivity`, locks `this.monitorC` in `class MyActivity`,[Trace 2] `void MyActivity.onDestroy()`, locks `this.monitorC` in `class MyActivity`, locks `this.monitorB` in `class MyActivity`] codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onPause():void, 76, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MyActivity.onPause()`,Method call: `void MyActivity$2.run()`, locks `this.monitorB` in `class MyActivity`, locks `this.monitorC` in `class MyActivity`,[Trace 2] `void MyActivity.onDestroy()`, locks `this.monitorC` in `class MyActivity`, locks `this.monitorB` in `class MyActivity`]

Loading…
Cancel
Save