[starvation][global] add android View models

Summary: Add models for `View` methods that schedule on the UI thread.

Reviewed By: skcho

Differential Revision: D21767954

fbshipit-source-id: 015441ea7
master
Nikos Gorogiannis 5 years ago committed by Facebook GitHub Bot
parent 7e902f241d
commit bad9ab08e7

@ -252,24 +252,35 @@ let schedules_work =
fun tenv pname -> matcher tenv pname [] fun tenv pname -> matcher tenv pname []
let schedules_work_on_ui_thread = let schedules_first_arg_on_ui_thread =
let open MethodMatcher in let open MethodMatcher in
let matcher = let matcher =
[ { default with { default with
classname= "java.lang.Object" classname= "java.lang.Object"
; methods= ; methods=
[ "postOnUiThread" [ "postOnUiThread"
; "postOnUiThreadDelayed" ; "postOnUiThreadDelayed"
; "postToUiThread" ; "postToUiThread"
; "runOnUiThread" ; "runOnUiThread"
; "runOnUiThreadAsync" ; "runOnUiThreadAsync"
; "runOnUiThreadAsyncWithDelay" ] } ] ; "runOnUiThreadAsyncWithDelay" ] }
|> of_records |> of_record
in
fun tenv pname -> matcher tenv pname []
let schedules_second_arg_on_ui_thread =
let open MethodMatcher in
let matcher =
{ default with
classname= "android.view.View"
; methods= ["post"; "postDelayed"; "postOnAnimation"] }
|> of_record
in in
fun tenv pname -> matcher tenv pname [] fun tenv pname -> matcher tenv pname []
let schedules_work_on_bg_thread = let schedules_first_arg_on_bg_thread =
let open MethodMatcher in let open MethodMatcher in
let matcher = let matcher =
[ {default with classname= "java.lang.Object"; methods= ["scheduleGuaranteedDelayed"]} [ {default with classname= "java.lang.Object"; methods= ["scheduleGuaranteedDelayed"]}

@ -52,11 +52,17 @@ val get_returned_executor :
Tenv.t -> Procname.t -> HilExp.t list -> scheduler_thread_constraint option Tenv.t -> Procname.t -> HilExp.t list -> scheduler_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 -> Procname.t -> bool val schedules_first_arg_on_ui_thread : Tenv.t -> Procname.t -> bool
(** method call known to directly schedule work on UI thread *) (** method call known to directly schedule the runnable object provided as first procedure argument
on the UI thread *)
val schedules_work_on_bg_thread : Tenv.t -> Procname.t -> bool val schedules_second_arg_on_ui_thread : Tenv.t -> Procname.t -> bool
(** method call known to directly schedule work on BG thread *) (** method call known to directly schedule the runnable object provided as second procedure argument
on a background thread *)
val schedules_first_arg_on_bg_thread : Tenv.t -> Procname.t -> bool
(** method call known to directly the runnable object provided as first procedure argument on a
background thread *)
val is_getMainLooper : Tenv.t -> Procname.t -> HilExp.t list -> bool val is_getMainLooper : Tenv.t -> Procname.t -> HilExp.t list -> bool

@ -95,9 +95,12 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
|> Option.value ~default:StarvationModels.ForUnknownThread |> Option.value ~default:StarvationModels.ForUnknownThread
in in
Some (runnable, thread) Some (runnable, thread)
| Some runnable :: _ when StarvationModels.schedules_work_on_ui_thread tenv callee -> | Some runnable :: _ when StarvationModels.schedules_first_arg_on_ui_thread tenv callee ->
Some (runnable, StarvationModels.ForUIThread) Some (runnable, StarvationModels.ForUIThread)
| Some runnable :: _ when StarvationModels.schedules_work_on_bg_thread tenv callee -> | _ :: Some runnable :: _ when StarvationModels.schedules_second_arg_on_ui_thread tenv callee
->
Some (runnable, StarvationModels.ForUIThread)
| Some runnable :: _ when StarvationModels.schedules_first_arg_on_bg_thread tenv callee ->
Some (runnable, StarvationModels.ForNonUIThread) Some (runnable, StarvationModels.ForNonUIThread)
| _ -> | _ ->
None None

@ -0,0 +1,45 @@
/*
* 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.
*/
import android.content.Context;
import android.view.View;
import java.util.concurrent.Executor;
class MyView extends View {
MyView(Context c) {
super(c);
}
Object monitorA, monitorB;
@ForNonUiThread private final Executor mNonUiThreadExecutor = null;
void scheduleOnBGThread() {
mNonUiThreadExecutor.execute(
new Runnable() {
@Override
public void run() {
synchronized (monitorA) {
synchronized (monitorB) {
}
}
}
});
}
void scheduleOnUIThread() {
post(
new Runnable() {
@Override
public void run() {
synchronized (monitorB) {
synchronized (monitorA) {
}
}
}
});
}
}

@ -31,6 +31,8 @@ codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onStart(
codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onStop():void, 48, STARVATION, no_bucket, ERROR, [[Trace 1] `void MyActivity.onStop()`, locks `this.monitorA` in `class MyActivity`,[Trace 2] `void MyActivity.onStop()`,Method call: `void MyActivity$1.run()`, locks `this.this$0.monitorA` in `class MyActivity$1`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onStop():void, 48, STARVATION, no_bucket, ERROR, [[Trace 1] `void MyActivity.onStop()`, locks `this.monitorA` in `class MyActivity`,[Trace 2] `void MyActivity.onStop()`,Method call: `void MyActivity$1.run()`, locks `this.this$0.monitorA` in `class MyActivity$1`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]
codetoanalyze/java/starvation-whole-program/MyServiceConnection.java, MyServiceConnection.onServiceConnected(android.content.ComponentName,android.os.IBinder):void, 37, STARVATION, no_bucket, ERROR, [`void MyServiceConnection.onServiceConnected(ComponentName,IBinder)`,Method call: `void MyServiceConnection.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/MyServiceConnection.java, MyServiceConnection.onServiceConnected(android.content.ComponentName,android.os.IBinder):void, 37, STARVATION, no_bucket, ERROR, [`void MyServiceConnection.onServiceConnected(ComponentName,IBinder)`,Method call: `void MyServiceConnection.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]
codetoanalyze/java/starvation-whole-program/MyServiceConnection.java, MyServiceConnection.onServiceDisconnected(android.content.ComponentName):void, 42, STARVATION, no_bucket, ERROR, [`void MyServiceConnection.onServiceDisconnected(ComponentName)`,Method call: `void MyServiceConnection.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/MyServiceConnection.java, MyServiceConnection.onServiceDisconnected(android.content.ComponentName):void, 42, STARVATION, no_bucket, ERROR, [`void MyServiceConnection.onServiceDisconnected(ComponentName)`,Method call: `void MyServiceConnection.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]
codetoanalyze/java/starvation-whole-program/MyView.java, MyView.scheduleOnBGThread():void, 21, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MyView.scheduleOnBGThread()`,Method call: `void MyView$1.run()`, locks `this.this$0.monitorA` in `class MyView$1`, locks `this.this$0.monitorB` in `class MyView$1`,[Trace 2] `void MyView.scheduleOnUIThread()`,Method call: `void MyView$2.run()`, locks `this.this$0.monitorB` in `class MyView$2`, locks `this.this$0.monitorA` in `class MyView$2`]
codetoanalyze/java/starvation-whole-program/MyView.java, MyView.scheduleOnUIThread():void, 34, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MyView.scheduleOnUIThread()`,Method call: `void MyView$2.run()`, locks `this.this$0.monitorB` in `class MyView$2`, locks `this.this$0.monitorA` in `class MyView$2`,[Trace 2] `void MyView.scheduleOnBGThread()`,Method call: `void MyView$1.run()`, locks `this.this$0.monitorA` in `class MyView$1`, locks `this.this$0.monitorB` in `class MyView$1`]
codetoanalyze/java/starvation-whole-program/StaticInitAttributes.java, StaticInitAttributes.postBlockingCallToUIExecutorBad():void, 52, STARVATION, no_bucket, ERROR, [`void StaticInitAttributes.postBlockingCallToUIExecutorBad()`,Method call: `void StaticInitAttributes$1.run()`,Method call: `void StaticInitAttributes.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/StaticInitAttributes.java, StaticInitAttributes.postBlockingCallToUIExecutorBad():void, 52, STARVATION, no_bucket, ERROR, [`void StaticInitAttributes.postBlockingCallToUIExecutorBad()`,Method call: `void StaticInitAttributes$1.run()`,Method call: `void StaticInitAttributes.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]
codetoanalyze/java/starvation-whole-program/StaticInitAttributes.java, StaticInitAttributes.postBlockingCallToUIHandlerBad():void, 64, STARVATION, no_bucket, ERROR, [`void StaticInitAttributes.postBlockingCallToUIHandlerBad()`,Method call: `void StaticInitAttributes$1.run()`,Method call: `void StaticInitAttributes.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/StaticInitAttributes.java, StaticInitAttributes.postBlockingCallToUIHandlerBad():void, 64, STARVATION, no_bucket, ERROR, [`void StaticInitAttributes.postBlockingCallToUIHandlerBad()`,Method call: `void StaticInitAttributes$1.run()`,Method call: `void StaticInitAttributes.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]
codetoanalyze/java/starvation-whole-program/ThreadScheduling.java, ThreadScheduling.scheduleBlockingCallOnContendedLockBad():void, 36, STARVATION, no_bucket, ERROR, [[Trace 1] `void ThreadScheduling.scheduleBlockingCallOnContendedLockBad()`,Method call: `void ThreadScheduling$2.run()`, locks `this.this$0.monitorA` in `class ThreadScheduling$2`,[Trace 2] `void ThreadScheduling.scheduleBlockingCallOnContendedLockBad()`,Method call: `void ThreadScheduling$1.run()`, locks `this.this$0.monitorA` in `class ThreadScheduling$1`,Method call: `void ThreadScheduling.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/ThreadScheduling.java, ThreadScheduling.scheduleBlockingCallOnContendedLockBad():void, 36, STARVATION, no_bucket, ERROR, [[Trace 1] `void ThreadScheduling.scheduleBlockingCallOnContendedLockBad()`,Method call: `void ThreadScheduling$2.run()`, locks `this.this$0.monitorA` in `class ThreadScheduling$2`,[Trace 2] `void ThreadScheduling.scheduleBlockingCallOnContendedLockBad()`,Method call: `void ThreadScheduling$1.run()`, locks `this.this$0.monitorA` in `class ThreadScheduling$1`,Method call: `void ThreadScheduling.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`]

Loading…
Cancel
Save