From 136281edb50a3398e303c866f8c7f27ce06c4cbb Mon Sep 17 00:00:00 2001 From: Nikos Gorogiannis Date: Wed, 3 Mar 2021 09:28:33 -0800 Subject: [PATCH] [starvation] add distinct issue for blocking IPC Binder calls Summary: `STARVATION` is currently used as a catch-all for several blocking events. This diff splits out `IPC_ON_UI_THREAD`. Reviewed By: skcho Differential Revision: D26691868 fbshipit-source-id: 618423793 --- infer/man/man1/infer-full.txt | 1 + infer/man/man1/infer-report.txt | 1 + infer/man/man1/infer.txt | 1 + infer/src/base/IssueType.ml | 5 ++ infer/src/base/IssueType.mli | 2 + infer/src/concurrency/StarvationModels.ml | 32 +++++++------ infer/src/concurrency/StarvationModels.mli | 2 + infer/src/concurrency/starvation.ml | 21 +++++++-- infer/src/concurrency/starvationDomain.ml | 21 +++++++-- infer/src/concurrency/starvationDomain.mli | 3 ++ .../java/starvation-whole-program/issues.exp | 46 +++++++++---------- .../codetoanalyze/java/starvation/issues.exp | 30 ++++++------ 12 files changed, 106 insertions(+), 59 deletions(-) diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt index 6019e7fe1..675c10392 100644 --- a/infer/man/man1/infer-full.txt +++ b/infer/man/man1/infer-full.txt @@ -508,6 +508,7 @@ OPTIONS INTEGER_OVERFLOW_U5 (disabled by default), INTERFACE_NOT_THREAD_SAFE (enabled by default), INVARIANT_CALL (disabled by default), + IPC_ON_UI_THREAD (enabled by default), IVAR_NOT_NULL_CHECKED (enabled by default), Internal_error (enabled by default), JAVASCRIPT_INJECTION (enabled by default), diff --git a/infer/man/man1/infer-report.txt b/infer/man/man1/infer-report.txt index 4f57f080d..667785059 100644 --- a/infer/man/man1/infer-report.txt +++ b/infer/man/man1/infer-report.txt @@ -200,6 +200,7 @@ OPTIONS INTEGER_OVERFLOW_U5 (disabled by default), INTERFACE_NOT_THREAD_SAFE (enabled by default), INVARIANT_CALL (disabled by default), + IPC_ON_UI_THREAD (enabled by default), IVAR_NOT_NULL_CHECKED (enabled by default), Internal_error (enabled by default), JAVASCRIPT_INJECTION (enabled by default), diff --git a/infer/man/man1/infer.txt b/infer/man/man1/infer.txt index 2ef1b668f..cb32b56d5 100644 --- a/infer/man/man1/infer.txt +++ b/infer/man/man1/infer.txt @@ -508,6 +508,7 @@ OPTIONS INTEGER_OVERFLOW_U5 (disabled by default), INTERFACE_NOT_THREAD_SAFE (enabled by default), INVARIANT_CALL (disabled by default), + IPC_ON_UI_THREAD (enabled by default), IVAR_NOT_NULL_CHECKED (enabled by default), Internal_error (enabled by default), JAVASCRIPT_INJECTION (enabled by default), diff --git a/infer/src/base/IssueType.ml b/infer/src/base/IssueType.ml index 49dc99ec6..060f7ea6c 100644 --- a/infer/src/base/IssueType.ml +++ b/infer/src/base/IssueType.ml @@ -710,6 +710,11 @@ let invariant_call = ~user_documentation:[%blob "../../documentation/issues/INVARIANT_CALL.md"] +let ipc_on_ui_thread = + register Warning ~id:"IPC_ON_UI_THREAD" Starvation + ~user_documentation:"A blocking `Binder` IPC call occurs on the UI thread." + + let javascript_injection = register ~id:"JAVASCRIPT_INJECTION" Error Quandary ~user_documentation:"Untrusted data flows into JavaScript." diff --git a/infer/src/base/IssueType.mli b/infer/src/base/IssueType.mli index f8a8ed8ad..41684a400 100644 --- a/infer/src/base/IssueType.mli +++ b/infer/src/base/IssueType.mli @@ -240,6 +240,8 @@ val internal_error : t val invariant_call : t +val ipc_on_ui_thread : t + val javascript_injection : t val lab_resource_leak : t diff --git a/infer/src/concurrency/StarvationModels.ml b/infer/src/concurrency/StarvationModels.ml index c56a62475..b90c0c8c8 100644 --- a/infer/src/concurrency/StarvationModels.ml +++ b/infer/src/concurrency/StarvationModels.ml @@ -104,12 +104,12 @@ let no_args_or_excessive_millis_and_nanos = function let is_future_get = - let open MethodMatcher in - of_record - { default with - classname= "java.util.concurrent.Future" - ; methods= ["get"] - ; actuals_pred= no_args_or_excessive_timeout_and_timeunit } + MethodMatcher.( + of_record + { default with + classname= "java.util.concurrent.Future" + ; methods= ["get"] + ; actuals_pred= no_args_or_excessive_timeout_and_timeunit }) let is_future_is_done = @@ -129,20 +129,24 @@ let may_block = classname= "java.util.concurrent.CountDownLatch" ; methods= ["await"] ; actuals_pred= no_args_or_excessive_timeout_and_timeunit } - (* 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) - } ; { default with classname= "android.os.AsyncTask" ; methods= ["get"] ; actuals_pred= no_args_or_excessive_timeout_and_timeunit } ]) +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) }) + + let is_monitor_wait = MethodMatcher.( of_record diff --git a/infer/src/concurrency/StarvationModels.mli b/infer/src/concurrency/StarvationModels.mli index 883450e38..f8de4e237 100644 --- a/infer/src/concurrency/StarvationModels.mli +++ b/infer/src/concurrency/StarvationModels.mli @@ -10,6 +10,8 @@ open! IStd val may_block : Tenv.t -> Procname.t -> HilExp.t list -> bool (** is the method call potentially blocking, given the actuals passed? *) +val may_do_ipc : Tenv.t -> Procname.t -> HilExp.t list -> bool + val is_strict_mode_violation : Tenv.t -> Procname.t -> HilExp.t list -> bool val is_monitor_wait : Tenv.t -> Procname.t -> HilExp.t list -> bool diff --git a/infer/src/concurrency/starvation.ml b/infer/src/concurrency/starvation.ml index b97d6f7d2..afbd8447a 100644 --- a/infer/src/concurrency/starvation.ml +++ b/infer/src/concurrency/starvation.ml @@ -331,6 +331,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct let ret_exp = HilExp.AccessExpression.base ret_base in let astate = do_work_scheduling tenv callee actuals loc astate in if may_block tenv callee actuals then Domain.blocking_call ~callee ~loc astate + else if may_do_ipc tenv callee actuals then Domain.ipc ~callee ~loc astate else do_call analysis_data ret_exp callee actuals loc astate | NoEffect -> (* in C++/Obj C we only care about deadlocks, not starvation errors *) @@ -458,6 +459,8 @@ module ReportMap : sig val add_deadlock : report_add_t + val add_ipc : report_add_t + val add_starvation : report_add_t val add_strict_mode_violation : report_add_t @@ -503,6 +506,10 @@ end = struct add tenv pattrs loc ltr message IssueType.deadlock map + let add_ipc tenv pattrs loc ltr message map = + add tenv pattrs loc ltr message IssueType.ipc_on_ui_thread map + + let add_starvation tenv pattrs loc ltr message map = add tenv pattrs loc ltr message IssueType.starvation map @@ -523,6 +530,7 @@ end = struct IssueType. [ deadlock ; lockless_violation + ; ipc_on_ui_thread ; starvation ; strict_mode_violation ; arbitrary_code_execution_under_lock ] @@ -585,8 +593,8 @@ let should_report_deadlock_on_current_proc current_elem endpoint_elem = (not Config.deduplicate) || match (endpoint_elem.CriticalPair.elem.event, current_elem.CriticalPair.elem.event) with - | _, (StrictModeCall _ | MayBlock _ | MonitorWait _ | MustNotOccurUnderLock _) - | (StrictModeCall _ | MayBlock _ | MonitorWait _ | MustNotOccurUnderLock _), _ -> + | _, (StrictModeCall _ | Ipc _ | MayBlock _ | MonitorWait _ | MustNotOccurUnderLock _) + | (StrictModeCall _ | Ipc _ | MayBlock _ | MonitorWait _ | MustNotOccurUnderLock _), _ -> (* should never happen *) L.die InternalError "Deadlock cannot occur without two lock events: %a" CriticalPair.pp current_elem @@ -661,7 +669,7 @@ let report_on_parallel_composition ~should_report_starvation tenv pattrs pair lo if CriticalPair.can_run_in_parallel pair other_pair then let acquisitions = other_pair.CriticalPair.elem.acquisitions in match other_pair.CriticalPair.elem.event with - | MayBlock _ as event + | (Ipc _ | MayBlock _) as event when should_report_starvation && Acquisitions.lock_is_held_in_other_thread tenv lock acquisitions -> let error_message = @@ -714,6 +722,13 @@ let report_on_pair ~analyze_ondemand tenv pattrs (pair : Domain.CriticalPair.t) (ltr, loc) in match event with + | Ipc _ when is_not_private && should_report_starvation -> + let error_message = + Format.asprintf "Method %a runs on UI thread and may perform blocking IPC; %a." pname_pp + pname Event.describe event + in + let ltr, loc = make_trace_and_loc () in + ReportMap.add_ipc tenv pattrs loc ltr error_message report_map | MayBlock _ when is_not_private && should_report_starvation -> let error_message = Format.asprintf "Method %a runs on UI thread and may block; %a." pname_pp pname diff --git a/infer/src/concurrency/starvationDomain.ml b/infer/src/concurrency/starvationDomain.ml index 62a0d863b..66181979a 100644 --- a/infer/src/concurrency/starvationDomain.ml +++ b/infer/src/concurrency/starvationDomain.ml @@ -189,6 +189,7 @@ end module Event = struct type t = + | Ipc of {callee: Procname.t; thread: ThreadDomain.t} | LockAcquire of {locks: Lock.t list; thread: ThreadDomain.t} | MayBlock of {callee: Procname.t; thread: ThreadDomain.t} | MonitorWait of {lock: Lock.t; thread: ThreadDomain.t} @@ -197,31 +198,34 @@ module Event = struct [@@deriving compare] let pp fmt = function + | Ipc {callee; thread} -> + F.fprintf fmt "Ipc(%a, %a)" Procname.pp callee ThreadDomain.pp thread | LockAcquire {locks; thread} -> F.fprintf fmt "LockAcquire(%a, %a)" (PrettyPrintable.pp_collection ~pp_item:Lock.pp) locks ThreadDomain.pp thread | MayBlock {callee; thread} -> F.fprintf fmt "MayBlock(%a, %a)" Procname.pp callee ThreadDomain.pp thread - | StrictModeCall {callee; thread} -> - F.fprintf fmt "StrictModeCall(%a, %a)" Procname.pp callee ThreadDomain.pp thread | MonitorWait {lock; thread} -> F.fprintf fmt "MonitorWait(%a, %a)" Lock.pp lock ThreadDomain.pp thread | MustNotOccurUnderLock {callee; thread} -> F.fprintf fmt "MustNotOccurUnderLock(%a, %a)" Procname.pp callee ThreadDomain.pp thread + | StrictModeCall {callee; thread} -> + F.fprintf fmt "StrictModeCall(%a, %a)" Procname.pp callee ThreadDomain.pp thread let describe fmt elem = match elem with | LockAcquire {locks} -> Pp.comma_seq Lock.pp_locks fmt locks - | MayBlock {callee} | StrictModeCall {callee} | MustNotOccurUnderLock {callee} -> + | Ipc {callee} | MayBlock {callee} | MustNotOccurUnderLock {callee} | StrictModeCall {callee} -> F.fprintf fmt "calls %a" describe_pname callee | MonitorWait {lock} -> F.fprintf fmt "calls `wait` on %a" Lock.describe lock let get_thread = function + | Ipc {thread} | LockAcquire {thread} | MayBlock {thread} | MonitorWait {thread} @@ -234,6 +238,8 @@ module Event = struct if ThreadDomain.equal thread (get_thread event) then event else match event with + | Ipc ipc -> + Ipc {ipc with thread} | LockAcquire lock_acquire -> LockAcquire {lock_acquire with thread} | MayBlock may_block -> @@ -264,11 +270,13 @@ module Event = struct let make_arbitrary_code_exec callee thread = MustNotOccurUnderLock {callee; thread} + let make_ipc callee thread = Ipc {callee; thread} + let get_acquired_locks = function LockAcquire {locks} -> locks | _ -> [] let apply_subst subst event = match event with - | MayBlock _ | StrictModeCall _ | MustNotOccurUnderLock _ -> + | Ipc _ | MayBlock _ | StrictModeCall _ | MustNotOccurUnderLock _ -> Some event | MonitorWait {lock; thread} -> ( match Lock.apply_subst subst lock with @@ -787,6 +795,11 @@ let blocking_call ~callee ~loc astate = make_call_with_event new_event ~loc astate +let ipc ~callee ~loc astate = + let new_event = Event.make_ipc callee astate.thread in + make_call_with_event new_event ~loc astate + + let wait_on_monitor ~loc formals actuals astate = match actuals with | exp :: _ -> diff --git a/infer/src/concurrency/starvationDomain.mli b/infer/src/concurrency/starvationDomain.mli index d3b5261b6..810f8afd4 100644 --- a/infer/src/concurrency/starvationDomain.mli +++ b/infer/src/concurrency/starvationDomain.mli @@ -57,6 +57,7 @@ end module Event : sig type t = + | Ipc of {callee: Procname.t; thread: ThreadDomain.t} | LockAcquire of {locks: Lock.t list; thread: ThreadDomain.t} | MayBlock of {callee: Procname.t; thread: ThreadDomain.t} | MonitorWait of {lock: Lock.t; thread: ThreadDomain.t} @@ -193,6 +194,8 @@ val release : t -> Lock.t list -> t val blocking_call : callee:Procname.t -> loc:Location.t -> t -> t +val ipc : callee:Procname.t -> loc:Location.t -> t -> t + val wait_on_monitor : loc:Location.t -> FormalMap.t -> HilExp.t list -> t -> t val future_get : callee:Procname.t -> loc:Location.t -> HilExp.t list -> t -> t diff --git a/infer/tests/codetoanalyze/java/starvation-whole-program/issues.exp b/infer/tests/codetoanalyze/java/starvation-whole-program/issues.exp index 1d5b69e39..58bad1434 100644 --- a/infer/tests/codetoanalyze/java/starvation-whole-program/issues.exp +++ b/infer/tests/codetoanalyze/java/starvation-whole-program/issues.exp @@ -1,42 +1,42 @@ -codetoanalyze/java/starvation-whole-program/AttributeFlows.java, AttributeFlows.postBlockingCallToAnnnotatedUIThreadBad():void, 84, STARVATION, no_bucket, ERROR, [`void AttributeFlows.postBlockingCallToAnnnotatedUIThreadBad()`,Method call: `void AttributeFlows$3.run()`,Method call: `void AttributeFlows.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation-whole-program/AttributeFlows.java, AttributeFlows.postRunnableFieldToUIThreadBad():void, 127, STARVATION, no_bucket, ERROR, [`void AttributeFlows.postRunnableFieldToUIThreadBad()`,Method call: `void AttributeFlows$6.run()`,Method call: `void AttributeFlows.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation-whole-program/AttributeFlows.java, AttributeFlows.postRunnableIndirectlyToUIThreadBad():void, 115, STARVATION, no_bucket, ERROR, [`void AttributeFlows.postRunnableIndirectlyToUIThreadBad()`,Method call: `void AttributeFlows$5.run()`,Method call: `void AttributeFlows.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation-whole-program/ConstructedAttributes.java, ConstructedAttributes.postBlockingCallToUIExecutorBad():void, 52, STARVATION, no_bucket, ERROR, [`void ConstructedAttributes.postBlockingCallToUIExecutorBad()`,Method call: `void ConstructedAttributes$1.run()`,Method call: `void ConstructedAttributes.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation-whole-program/ConstructedAttributes.java, ConstructedAttributes.postBlockingCallToUIHandlerBad():void, 64, STARVATION, no_bucket, ERROR, [`void ConstructedAttributes.postBlockingCallToUIHandlerBad()`,Method call: `void ConstructedAttributes$1.run()`,Method call: `void ConstructedAttributes.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/AttributeFlows.java, AttributeFlows.postBlockingCallToAnnnotatedUIThreadBad():void, 84, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void AttributeFlows.postBlockingCallToAnnnotatedUIThreadBad()`,Method call: `void AttributeFlows$3.run()`,Method call: `void AttributeFlows.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/AttributeFlows.java, AttributeFlows.postRunnableFieldToUIThreadBad():void, 127, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void AttributeFlows.postRunnableFieldToUIThreadBad()`,Method call: `void AttributeFlows$6.run()`,Method call: `void AttributeFlows.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/AttributeFlows.java, AttributeFlows.postRunnableIndirectlyToUIThreadBad():void, 115, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void AttributeFlows.postRunnableIndirectlyToUIThreadBad()`,Method call: `void AttributeFlows$5.run()`,Method call: `void AttributeFlows.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/ConstructedAttributes.java, ConstructedAttributes.postBlockingCallToUIExecutorBad():void, 52, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void ConstructedAttributes.postBlockingCallToUIExecutorBad()`,Method call: `void ConstructedAttributes$1.run()`,Method call: `void ConstructedAttributes.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/ConstructedAttributes.java, ConstructedAttributes.postBlockingCallToUIHandlerBad():void, 64, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void ConstructedAttributes.postBlockingCallToUIHandlerBad()`,Method call: `void ConstructedAttributes$1.run()`,Method call: `void ConstructedAttributes.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/Deadlock.java, Deadlock.postDeadlockBad():void, 19, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void Deadlock.postDeadlockBad()`,Method call: `void Deadlock$1.run()`, locks `this.this$0.monitorA` in `class Deadlock$1`, locks `this.this$0.monitorB` in `class Deadlock$1`,[Trace 2] `void Deadlock.postDeadlockBad()`,Method call: `void Deadlock$2.run()`, locks `this.this$0.monitorB` in `class Deadlock$2`, locks `this.this$0.monitorA` in `class Deadlock$2`] codetoanalyze/java/starvation-whole-program/Deadlock.java, Deadlock.postDeadlockBad():void, 30, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void Deadlock.postDeadlockBad()`,Method call: `void Deadlock$2.run()`, locks `this.this$0.monitorB` in `class Deadlock$2`, locks `this.this$0.monitorA` in `class Deadlock$2`,[Trace 2] `void Deadlock.postDeadlockBad()`,Method call: `void Deadlock$1.run()`, locks `this.this$0.monitorA` in `class Deadlock$1`, locks `this.this$0.monitorB` in `class Deadlock$1`] codetoanalyze/java/starvation-whole-program/Deadlock.java, Deadlock.postOnBGThreadBad():void, 73, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void Deadlock.postOnBGThreadBad()`,Method call: `void Deadlock$5.run()`, locks `this.this$0.monitorE` in `class Deadlock$5`, locks `this.this$0.monitorF` in `class Deadlock$5`,[Trace 2] `void Deadlock.postOnBGThreadBad()`,Method call: `void Deadlock$6.run()`, locks `this.this$0.monitorF` in `class Deadlock$6`, locks `this.this$0.monitorE` in `class Deadlock$6`] codetoanalyze/java/starvation-whole-program/Deadlock.java, Deadlock.postOnBGThreadBad():void, 84, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void Deadlock.postOnBGThreadBad()`,Method call: `void Deadlock$6.run()`, locks `this.this$0.monitorF` in `class Deadlock$6`, locks `this.this$0.monitorE` in `class Deadlock$6`,[Trace 2] `void Deadlock.postOnBGThreadBad()`,Method call: `void Deadlock$5.run()`, locks `this.this$0.monitorE` in `class Deadlock$5`, locks `this.this$0.monitorF` in `class Deadlock$5`] -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/ImplicitConstructor.java, ImplicitConstructor.postBlockingCallToUIExecutorBad():void, 54, STARVATION, no_bucket, ERROR, [`void ImplicitConstructor.postBlockingCallToUIExecutorBad()`,Method call: `void ImplicitConstructor$1.run()`,Method call: `void ImplicitConstructor.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation-whole-program/ImplicitConstructor.java, ImplicitConstructor.postBlockingCallToUIHandlerBad():void, 66, STARVATION, no_bucket, ERROR, [`void ImplicitConstructor.postBlockingCallToUIHandlerBad()`,Method call: `void ImplicitConstructor$1.run()`,Method call: `void ImplicitConstructor.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/DirectStarvation.java, DirectStarvation.postBlockingCallToUIThreadBad():void, 29, IPC_ON_UI_THREAD, no_bucket, WARNING, [`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/ImplicitConstructor.java, ImplicitConstructor.postBlockingCallToUIExecutorBad():void, 54, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void ImplicitConstructor.postBlockingCallToUIExecutorBad()`,Method call: `void ImplicitConstructor$1.run()`,Method call: `void ImplicitConstructor.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/ImplicitConstructor.java, ImplicitConstructor.postBlockingCallToUIHandlerBad():void, 66, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void ImplicitConstructor.postBlockingCallToUIHandlerBad()`,Method call: `void ImplicitConstructor$1.run()`,Method call: `void ImplicitConstructor.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.this$0.monitorA` in `class IndirectStarvation$1`,[Trace 2] `void IndirectStarvation.postBlockingCallToBackgroundThreadAndLockBad()`,Method call: `void IndirectStarvation$2.run()`, locks `this.this$0.monitorA` in `class IndirectStarvation$2`,Method call: `void IndirectStarvation.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/MainMethod.java, MainMethod.main(java.lang.String[]):void, 24, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MainMethod.main(String[])`,Method call: `void MainMethod$1.run()`, locks `MainMethod.monitorA` in `class MainMethod`, locks `MainMethod.monitorB` in `class MainMethod`,[Trace 2] `void MainMethod.main(String[])`, locks `MainMethod.monitorB` in `class MainMethod`, locks `MainMethod.monitorA` in `class MainMethod`] codetoanalyze/java/starvation-whole-program/MainMethod.java, MainMethod.main(java.lang.String[]):void, 26, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MainMethod.main(String[])`, locks `MainMethod.monitorB` in `class MainMethod`, locks `MainMethod.monitorA` in `class MainMethod`,[Trace 2] `void MainMethod.main(String[])`,Method call: `void MainMethod$1.run()`, locks `MainMethod.monitorA` in `class MainMethod`, locks `MainMethod.monitorB` in `class MainMethod`] -codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.postToUIThreadBad():void, 165, STARVATION, no_bucket, ERROR, [`void ModeledExecutors.postToUIThreadBad()`,Method call: `void ModeledExecutors$12.run()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.scheduleBlockingCallToUIThreadBad():void, 140, STARVATION, no_bucket, ERROR, [`void ModeledExecutors.scheduleBlockingCallToUIThreadBad()`,Method call: `void ModeledExecutors$10.run()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.postToUIThreadBad():void, 165, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void ModeledExecutors.postToUIThreadBad()`,Method call: `void ModeledExecutors$12.run()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.scheduleBlockingCallToUIThreadBad():void, 140, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void ModeledExecutors.scheduleBlockingCallToUIThreadBad()`,Method call: `void ModeledExecutors$10.run()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.scheduleGuaranteedDelayedDeadlockBad():void, 97, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void ModeledExecutors.scheduleGuaranteedDelayedDeadlockBad()`,Method call: `void ModeledExecutors$7.run()`, locks `this.this$0.monitorA` in `class ModeledExecutors$7`, locks `this.this$0.monitorB` in `class ModeledExecutors$7`,[Trace 2] `void ModeledExecutors.scheduleGuaranteedDelayedDeadlockBad()`,Method call: `void ModeledExecutors$8.run()`, locks `this.this$0.monitorB` in `class ModeledExecutors$8`, locks `this.this$0.monitorA` in `class ModeledExecutors$8`] codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.scheduleGuaranteedDelayedDeadlockBad():void, 110, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void ModeledExecutors.scheduleGuaranteedDelayedDeadlockBad()`,Method call: `void ModeledExecutors$8.run()`, locks `this.this$0.monitorB` in `class ModeledExecutors$8`, locks `this.this$0.monitorA` in `class ModeledExecutors$8`,[Trace 2] `void ModeledExecutors.scheduleGuaranteedDelayedDeadlockBad()`,Method call: `void ModeledExecutors$7.run()`, locks `this.this$0.monitorA` in `class ModeledExecutors$7`, locks `this.this$0.monitorB` in `class ModeledExecutors$7`] -codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.staticPostBlockingCallToUIThreadBad():void, 50, 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, 72, 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, 61, 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/ModeledExecutors.java, ModeledExecutors.submitBadCallableToUIThreadBad():void, 154, STARVATION, no_bucket, ERROR, [`void ModeledExecutors.submitBadCallableToUIThreadBad()`,Method call: `Object ModeledExecutors$11.call()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.submitBlockingCallToUIThreadBad():void, 127, STARVATION, no_bucket, ERROR, [`void ModeledExecutors.submitBlockingCallToUIThreadBad()`,Method call: `void ModeledExecutors$9.run()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation-whole-program/ModeledHandler.java, ModeledHandler.postBlockingCallToUIThreadBad():void, 27, STARVATION, no_bucket, ERROR, [`void ModeledHandler.postBlockingCallToUIThreadBad()`,Method call: `void ModeledHandler$1.run()`,Method call: `void ModeledHandler.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/ModeledExecutors.java, ModeledExecutors.staticPostBlockingCallToUIThreadBad():void, 50, IPC_ON_UI_THREAD, no_bucket, WARNING, [`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, 72, IPC_ON_UI_THREAD, no_bucket, WARNING, [`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, 61, IPC_ON_UI_THREAD, no_bucket, WARNING, [`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/ModeledExecutors.java, ModeledExecutors.submitBadCallableToUIThreadBad():void, 154, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void ModeledExecutors.submitBadCallableToUIThreadBad()`,Method call: `Object ModeledExecutors$11.call()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/ModeledExecutors.java, ModeledExecutors.submitBlockingCallToUIThreadBad():void, 127, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void ModeledExecutors.submitBlockingCallToUIThreadBad()`,Method call: `void ModeledExecutors$9.run()`,Method call: `void ModeledExecutors.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/ModeledHandler.java, ModeledHandler.postBlockingCallToUIThreadBad():void, 27, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void ModeledHandler.postBlockingCallToUIThreadBad()`,Method call: `void ModeledHandler$1.run()`,Method call: `void ModeledHandler.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onCreate(android.os.Bundle):void, 28, IPC_ON_UI_THREAD, no_bucket, WARNING, [`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.this$0.monitorB` in `class MyActivity$2`, locks `this.this$0.monitorC` in `class MyActivity$2`] 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.this$0.monitorB` in `class MyActivity$2`, locks `this.this$0.monitorC` in `class MyActivity$2`,[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.onRestart():void, 38, STARVATION, no_bucket, ERROR, [`void MyActivity.onRestart()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onRestart():void, 38, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void MyActivity.onRestart()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onResume():void, 95, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MyActivity.onResume()`, locks `this.FP_monitorD` in `class MyActivity`, locks `this.FP_monitorE` in `class MyActivity`,[Trace 2] `void MyActivity.onResume()`,Method call: `void MyActivity$3.run()`, locks `this.this$0.FP_monitorE` in `class MyActivity$3`, locks `this.this$0.FP_monitorD` in `class MyActivity$3`] codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onResume():void, 100, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void MyActivity.onResume()`,Method call: `void MyActivity$3.run()`, locks `this.this$0.FP_monitorE` in `class MyActivity$3`, locks `this.this$0.FP_monitorD` in `class MyActivity$3`,[Trace 2] `void MyActivity.onResume()`, locks `this.FP_monitorD` in `class MyActivity`, locks `this.FP_monitorE` in `class MyActivity`] -codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onStart():void, 33, STARVATION, no_bucket, ERROR, [`void MyActivity.onStart()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation-whole-program/MyActivity.java, MyActivity.onStart():void, 33, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void MyActivity.onStart()`,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.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.onServiceConnected(android.content.ComponentName,android.os.IBinder):void, 37, IPC_ON_UI_THREAD, no_bucket, WARNING, [`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, IPC_ON_UI_THREAD, no_bucket, WARNING, [`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.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.postBlockingCallToUIExecutorBad():void, 52, IPC_ON_UI_THREAD, no_bucket, WARNING, [`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, IPC_ON_UI_THREAD, no_bucket, WARNING, [`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.scheduleBlockingCallOnContendedLockViaInheritanceBad():void, 89, STARVATION, no_bucket, ERROR, [[Trace 1] `void ThreadScheduling.scheduleBlockingCallOnContendedLockViaInheritanceBad()`,Method call: `void ThreadScheduling$5.run()`, locks `this.this$0.monitorD` in `class ThreadScheduling$5`,[Trace 2] `void ThreadScheduling.scheduleBlockingCallOnContendedLockViaInheritanceBad()`,Method call: `void ThreadScheduling$BadThread.run()`, locks `this.this$0.monitorD` in `class ThreadScheduling$BadThread`,Method call: `void ThreadScheduling.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation-whole-program/ThreadScheduling.java, ThreadScheduling.scheduleDeadlockBad():void, 60, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void ThreadScheduling.scheduleDeadlockBad()`,Method call: `void ThreadScheduling$3.run()`, locks `this.this$0.monitorB` in `class ThreadScheduling$3`, locks `this.this$0.monitorC` in `class ThreadScheduling$3`,[Trace 2] `void ThreadScheduling.scheduleDeadlockBad()`,Method call: `void ThreadScheduling$4.run()`, locks `this.this$0.monitorC` in `class ThreadScheduling$4`, locks `this.this$0.monitorB` in `class ThreadScheduling$4`] diff --git a/infer/tests/codetoanalyze/java/starvation/issues.exp b/infer/tests/codetoanalyze/java/starvation/issues.exp index 0e82b7a83..ec4d64026 100644 --- a/infer/tests/codetoanalyze/java/starvation/issues.exp +++ b/infer/tests/codetoanalyze/java/starvation/issues.exp @@ -1,8 +1,8 @@ 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, STARVATION, no_bucket, ERROR, [`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, STARVATION, no_bucket, ERROR, [`void Binders.interBad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation/Binders.java, Binders.intraBad():void, 36, STARVATION, no_bucket, ERROR, [`void Binders.intraBad()`,Method call: `void Binders.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +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/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()`] @@ -28,17 +28,17 @@ codetoanalyze/java/starvation/LockSensitivity.java, LockSensitivity.FP_assertHol codetoanalyze/java/starvation/LocklessTests.java, LocklessTestsA.locklessMethod():void, 23, LOCKLESS_VIOLATION, no_bucket, ERROR, [`void LocklessTestsA.locklessMethod()`, locks `this` in `class LocklessTestsA`] codetoanalyze/java/starvation/LocklessTests.java, LocklessTestsB.locklessMethod():void, 39, LOCKLESS_VIOLATION, no_bucket, ERROR, [`void LocklessTestsB.locklessMethod()`, locks `this` in `class LocklessTestsB`] 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)`] -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)`] +codetoanalyze/java/starvation/MainThreadTest.java, AnnotatedClass.callTransactBad(MainThreadTest):void, 30, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void AnnotatedClass.callTransactBad(MainThreadTest)`,Method call: `void MainThreadTest.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/MainThreadTest.java, MainThreadTest.callTransactBad():void, 23, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void MainThreadTest.callTransactBad()`,Method call: `void MainThreadTest.doTransact()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] 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)`] -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)`] -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)`] -codetoanalyze/java/starvation/MyActivity.java, MyActivity.onRestart():void, 38, STARVATION, no_bucket, ERROR, [`void MyActivity.onRestart()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation/MyActivity.java, MyActivity.onResume():void, 43, STARVATION, no_bucket, ERROR, [`void MyActivity.onResume()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation/MyActivity.java, MyActivity.onStart():void, 33, STARVATION, no_bucket, ERROR, [`void MyActivity.onStart()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation/MyActivity.java, MyActivity.onStop():void, 53, STARVATION, no_bucket, ERROR, [`void MyActivity.onStop()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/MyActivity.java, MyActivity.onCreate(android.os.Bundle):void, 28, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void MyActivity.onCreate(Bundle)`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/MyActivity.java, MyActivity.onDestroy():void, 58, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void MyActivity.onDestroy()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/MyActivity.java, MyActivity.onPause():void, 48, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void MyActivity.onPause()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/MyActivity.java, MyActivity.onRestart():void, 38, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void MyActivity.onRestart()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/MyActivity.java, MyActivity.onResume():void, 43, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void MyActivity.onResume()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/MyActivity.java, MyActivity.onStart():void, 33, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void MyActivity.onStart()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/MyActivity.java, MyActivity.onStop():void, 53, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void MyActivity.onStop()`,Method call: `void MyActivity.bad()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation/NonBlk.java, NonBlk.deadlockABBad():void, 33, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void NonBlk.deadlockABBad()`, locks `this` in `class NonBlk`, locks `this.future` in `class NonBlk`,[Trace 2] `void NonBlk.deadlockBABad()`, locks `this.future` in `class NonBlk`, locks `this` in `class NonBlk`] codetoanalyze/java/starvation/NonBlk.java, NonBlk.deadlockBABad():void, 40, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void NonBlk.deadlockBABad()`, locks `this.future` in `class NonBlk`, locks `this` in `class NonBlk`,[Trace 2] `void NonBlk.deadlockABBad()`, locks `this` in `class NonBlk`, locks `this.future` in `class NonBlk`] codetoanalyze/java/starvation/NotUnderLock.java, NotUnderLock.firstAcquisitionBad():void, 17, ARBITRARY_CODE_EXECUTION_UNDER_LOCK, no_bucket, ERROR, [`void NotUnderLock.firstAcquisitionBad()`, locks `this` in `class NotUnderLock`,Method call: `void NotUnderLock.callFutureSetOk()`,calls `boolean SettableFuture.set(Object)`] @@ -49,11 +49,11 @@ codetoanalyze/java/starvation/ObjWait.java, ObjWait.waitOnMainWithoutTimeoutBad( codetoanalyze/java/starvation/Parameters.java, Parameters.anotherWayEmulateSyncBad():void, 39, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void Parameters.anotherWayEmulateSyncBad()`, locks `this.someObject` in `class Parameters`, locks `this` in `class Parameters`,[Trace 2] `void Parameters.oneWayEmulateSyncBad()`, locks `this` in `class Parameters`,Method call: `void Parameters.emulateSynchronized(Parameters)`, locks `this.someObject` in `class Parameters`] codetoanalyze/java/starvation/Parameters.java, Parameters.oneWayEmulateSyncBad():void, 34, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void Parameters.oneWayEmulateSyncBad()`, locks `this` in `class Parameters`,Method call: `void Parameters.emulateSynchronized(Parameters)`, locks `this.someObject` in `class Parameters`,[Trace 2] `void Parameters.anotherWayEmulateSyncBad()`, locks `this.someObject` in `class Parameters`, locks `this` in `class Parameters`] codetoanalyze/java/starvation/Parameters.java, Parameters.otherWaySyncOnParamBad(java.lang.Object):void, 20, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void Parameters.otherWaySyncOnParamBad(Object)`, locks `x` in `class java.lang.Object`, locks `this` in `class Parameters`,[Trace 2] `void Parameters.oneWaySyncOnParamBad(Object)`, locks `this` in `class Parameters`,Method call: `void Parameters.syncOnParam(Object)`, locks `x` in `class java.lang.Object`] -codetoanalyze/java/starvation/PubPriv.java, PubPriv.alsoBad():void, 25, STARVATION, no_bucket, ERROR, [`void PubPriv.alsoBad()`,Method call: `void PubPriv.transactBad()`,Method call: `void PubPriv.doTransactOk()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/PubPriv.java, PubPriv.alsoBad():void, 25, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void PubPriv.alsoBad()`,Method call: `void PubPriv.transactBad()`,Method call: `void PubPriv.doTransactOk()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation/PubPriv.java, PubPriv.callAnotherWayBad():void, 53, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void PubPriv.callAnotherWayBad()`,Method call: `void PubPriv.anotherWayOk()`, locks `this.lockB` in `class PubPriv`, locks `this.lockA` in `class PubPriv`,[Trace 2] `void PubPriv.callOneWayBad()`,Method call: `void PubPriv.oneWayOk()`, locks `this.lockA` in `class PubPriv`, locks `this.lockB` in `class PubPriv`] codetoanalyze/java/starvation/PubPriv.java, PubPriv.callOneWayBad():void, 49, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void PubPriv.callOneWayBad()`,Method call: `void PubPriv.oneWayOk()`, locks `this.lockA` in `class PubPriv`, locks `this.lockB` in `class PubPriv`,[Trace 2] `void PubPriv.callAnotherWayBad()`,Method call: `void PubPriv.anotherWayOk()`, locks `this.lockB` in `class PubPriv`, locks `this.lockA` in `class PubPriv`] -codetoanalyze/java/starvation/PubPriv.java, PubPriv.transactBad():void, 21, STARVATION, no_bucket, ERROR, [`void PubPriv.transactBad()`,Method call: `void PubPriv.doTransactOk()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] -codetoanalyze/java/starvation/ServiceOnUIThread.java, ServiceOnUIThread.onBind(android.content.Intent):android.os.IBinder, 19, STARVATION, no_bucket, ERROR, [`IBinder ServiceOnUIThread.onBind(Intent)`,Method call: `void ServiceOnUIThread.transactBad()`,calls `boolean IBinder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/PubPriv.java, PubPriv.transactBad():void, 21, IPC_ON_UI_THREAD, no_bucket, WARNING, [`void PubPriv.transactBad()`,Method call: `void PubPriv.doTransactOk()`,calls `boolean Binder.transact(int,Parcel,Parcel,int)`] +codetoanalyze/java/starvation/ServiceOnUIThread.java, ServiceOnUIThread.onBind(android.content.Intent):android.os.IBinder, 19, IPC_ON_UI_THREAD, no_bucket, WARNING, [`IBinder ServiceOnUIThread.onBind(Intent)`,Method call: `void ServiceOnUIThread.transactBad()`,calls `boolean IBinder.transact(int,Parcel,Parcel,int)`] codetoanalyze/java/starvation/StaticLock.java, StaticLock.lockOtherClassAnotherWayBad():void, 29, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void StaticLock.lockOtherClassAnotherWayBad()`, locks `this` in `class StaticLock`,Method call: `void StaticLock.staticSynced()`, locks `StaticLock.class`,[Trace 2] `void StaticLock.lockOtherClassOneWayBad()`, locks `StaticLock.class`, locks `this` in `class StaticLock`] codetoanalyze/java/starvation/StaticLock.java, StaticLock.lockOtherClassOneWayBad():void, 23, DEADLOCK, no_bucket, ERROR, [[Trace 1] `void StaticLock.lockOtherClassOneWayBad()`, locks `StaticLock.class`, locks `this` in `class StaticLock`,[Trace 2] `void StaticLock.lockOtherClassAnotherWayBad()`, locks `this` in `class StaticLock`,Method call: `void StaticLock.staticSynced()`, locks `StaticLock.class`] codetoanalyze/java/starvation/StrictModeViolation.java, StrictModeViolation.violateStrictModeBad():void, 17, STRICT_MODE_VIOLATION, no_bucket, ERROR, [`void StrictModeViolation.violateStrictModeBad()`,calls `boolean File.canRead()`]