[starvation] fix reported location

Summary:
The reported location was always the start of the enclosing procedure, which is wrong in many ways.
A nice side-effect is that some code can then be eliminated and Ondemand.analyze used, avoiding getting the procdescs in the process.

Reviewed By: jeremydubreil

Differential Revision: D8056306

fbshipit-source-id: 67c2c8d
master
Nikos Gorogiannis 7 years ago committed by Facebook Github Bot
parent 736badbb2f
commit 5e8b118151

@ -318,7 +318,7 @@ let sql_injection_risk = from_string "SQL_INJECTION_RISK"
let stack_variable_address_escape = from_string ~enabled:false "STACK_VARIABLE_ADDRESS_ESCAPE" let stack_variable_address_escape = from_string ~enabled:false "STACK_VARIABLE_ADDRESS_ESCAPE"
let starvation = from_string "STARVATION" let starvation = from_string "STARVATION" ~hum:"UI Thread Starvation"
let static_initialization_order_fiasco = from_string "STATIC_INITIALIZATION_ORDER_FIASCO" let static_initialization_order_fiasco = from_string "STATIC_INITIALIZATION_ORDER_FIASCO"

@ -9,6 +9,7 @@
open! IStd open! IStd
module F = Format module F = Format
module L = Logging module L = Logging
module MF = MarkupFormatter
let debug fmt = L.(debug Analysis Verbose fmt) let debug fmt = L.(debug Analysis Verbose fmt)
@ -133,28 +134,29 @@ let analyze_procedure {Callbacks.proc_desc; tenv; summary} =
Payload.update_summary lock_order summary ) Payload.update_summary lock_order summary )
let make_trace_with_header ?(header= "") elem start_loc pname = let make_trace_with_header ?(header= "") elem pname =
let trace = StarvationDomain.LockOrder.make_loc_trace elem in let trace = StarvationDomain.LockOrder.make_loc_trace elem in
let trace_descr = Format.asprintf "%s %a" header Typ.Procname.pp pname in let trace_descr = Format.asprintf "%s %a" header (MF.wrap_monospaced Typ.Procname.pp) pname in
let start_loc =
List.hd trace |> Option.value_map ~default:Location.dummy ~f:(fun lt -> lt.Errlog.lt_loc)
in
Errlog.make_trace_element 0 start_loc trace_descr [] :: trace Errlog.make_trace_element 0 start_loc trace_descr [] :: trace
let make_loc_trace pname trace_id start_loc elem = let make_loc_trace pname trace_id elem =
let header = Printf.sprintf "[Trace %d] " trace_id in let header = Printf.sprintf "[Trace %d] " trace_id in
make_trace_with_header ~header elem start_loc pname make_trace_with_header ~header elem pname
let get_summaries_of_methods_in_class get_proc_desc tenv current_pdesc clazz = let get_summaries_of_methods_in_class tenv clazz =
let tstruct_opt = Tenv.lookup tenv clazz in let tstruct_opt = Tenv.lookup tenv clazz in
let methods = let methods =
Option.value_map tstruct_opt ~default:[] ~f:(fun tstruct -> tstruct.Typ.Struct.methods) Option.value_map tstruct_opt ~default:[] ~f:(fun tstruct -> tstruct.Typ.Struct.methods)
in in
let pdescs = List.rev_filter_map methods ~f:get_proc_desc in let summaries = List.rev_filter_map methods ~f:Ondemand.analyze_proc_name in
let get_summary callee_pdesc = List.rev_filter_map summaries ~f:(fun sum ->
Payload.read current_pdesc (Procdesc.get_proc_name callee_pdesc) Option.map sum.Summary.payloads.Payloads.starvation ~f:(fun p ->
|> Option.map ~f:(fun summary -> (callee_pdesc, summary)) (Summary.get_proc_name sum, p) ) )
in
List.rev_filter_map pdescs ~f:get_summary
let log_issue current_pname current_loc ltr exn = let log_issue current_pname current_loc ltr exn =
@ -198,11 +200,11 @@ let should_report_deadlock_on_current_proc current_elem endpoint_elem =
inner class but this is no longer obvious in the path, because of nested-class path normalisation. inner class but this is no longer obvious in the path, because of nested-class path normalisation.
The net effect of the above issues is that we will only see these locks in conflicting pairs The net effect of the above issues is that we will only see these locks in conflicting pairs
once, as opposed to twice with all other deadlock pairs. *) once, as opposed to twice with all other deadlock pairs. *)
let report_deadlocks get_proc_desc tenv current_pdesc (summary, current_main) = let report_deadlocks tenv current_pdesc (summary, current_main) =
let open StarvationDomain in let open StarvationDomain in
let current_loc = Procdesc.get_loc current_pdesc in let current_loc = Procdesc.get_loc current_pdesc in
let current_pname = Procdesc.get_proc_name current_pdesc in let current_pname = Procdesc.get_proc_name current_pdesc in
let report_endpoint_elem current_elem endpoint_pname endpoint_loc elem = let report_endpoint_elem current_elem endpoint_pname elem =
if if
LockOrder.may_deadlock current_elem elem LockOrder.may_deadlock current_elem elem
&& should_report_deadlock_on_current_proc current_elem elem && should_report_deadlock_on_current_proc current_elem elem
@ -213,14 +215,16 @@ let report_deadlocks get_proc_desc tenv current_pdesc (summary, current_main) =
let error_message = let error_message =
Format.asprintf Format.asprintf
"Potential deadlock.@.Trace 1 (starts at %a), %a.@.Trace 2 (starts at %a), %a." "Potential deadlock.@.Trace 1 (starts at %a), %a.@.Trace 2 (starts at %a), %a."
Typ.Procname.pp current_pname LockOrder.pp current_elem Typ.Procname.pp (MF.wrap_monospaced Typ.Procname.pp)
current_pname LockOrder.pp current_elem
(MF.wrap_monospaced Typ.Procname.pp)
endpoint_pname LockOrder.pp elem endpoint_pname LockOrder.pp elem
in in
let exn = let exn =
Exceptions.Checkers (IssueType.deadlock, Localise.verbatim_desc error_message) Exceptions.Checkers (IssueType.deadlock, Localise.verbatim_desc error_message)
in in
let first_trace = List.rev (make_loc_trace current_pname 1 current_loc current_elem) in let first_trace = List.rev (make_loc_trace current_pname 1 current_elem) in
let second_trace = make_loc_trace endpoint_pname 2 endpoint_loc elem in let second_trace = make_loc_trace endpoint_pname 2 elem in
let ltr = List.rev_append first_trace second_trace in let ltr = List.rev_append first_trace second_trace in
log_issue current_pname current_loc ltr exn log_issue current_pname current_loc ltr exn
| _, _ -> | _, _ ->
@ -237,39 +241,34 @@ let report_deadlocks get_proc_desc tenv current_pdesc (summary, current_main) =
| Some endpoint_class -> | Some endpoint_class ->
(* get the class of the root variable of the lock in the endpoint event (* get the class of the root variable of the lock in the endpoint event
and retrieve all the summaries of the methods of that class *) and retrieve all the summaries of the methods of that class *)
let endpoint_summaries = let endpoint_summaries = get_summaries_of_methods_in_class tenv endpoint_class in
get_summaries_of_methods_in_class get_proc_desc tenv current_pdesc endpoint_class
in
(* for each summary related to the endpoint, analyse and report on its pairs *) (* for each summary related to the endpoint, analyse and report on its pairs *)
List.iter endpoint_summaries ~f:(fun (endpoint_pdesc, (summary, endpoint_main)) -> List.iter endpoint_summaries ~f:(fun (endpoint_pname, (summary, endpoint_main)) ->
if not (current_main && endpoint_main) then if not (current_main && endpoint_main) then
let endpoint_loc = Procdesc.get_loc endpoint_pdesc in LockOrderDomain.iter (report_endpoint_elem elem endpoint_pname) summary )
let endpoint_pname = Procdesc.get_proc_name endpoint_pdesc in
LockOrderDomain.iter
(report_endpoint_elem elem endpoint_pname endpoint_loc)
summary )
in in
LockOrderDomain.iter report_on_current_elem summary LockOrderDomain.iter report_on_current_elem summary
let report_blocks_on_main_thread get_proc_desc tenv current_pdesc summary = let report_blocks_on_main_thread tenv current_pdesc summary =
let open StarvationDomain in let open StarvationDomain in
let current_loc = Procdesc.get_loc current_pdesc in let current_loc = Procdesc.get_loc current_pdesc in
let current_pname = Procdesc.get_proc_name current_pdesc in let current_pname = Procdesc.get_proc_name current_pdesc in
let report_remote_block current_elem current_lock endpoint_pname endpoint_loc endpoint_elem = let report_remote_block current_elem current_lock endpoint_pname endpoint_elem =
match endpoint_elem with match endpoint_elem with
| { LockOrder.first= Some {LockEvent.event= LockEvent.LockAcquire lock} | { LockOrder.first= Some {LockEvent.event= LockEvent.LockAcquire lock}
; eventually= {LockEvent.event= LockEvent.MayBlock block_descr} } ; eventually= {LockEvent.event= LockEvent.MayBlock block_descr} }
when LockIdentity.equal current_lock lock -> when LockIdentity.equal current_lock lock ->
let error_message = let error_message =
Format.asprintf "UI thread %a, which may be held by another thread which %s" Format.asprintf "UI thread method %a %a, which may be held by another thread which %s"
LockIdentity.pp lock block_descr (MF.wrap_monospaced Typ.Procname.pp)
current_pname LockIdentity.pp lock block_descr
in in
let exn = let exn =
Exceptions.Checkers (IssueType.starvation, Localise.verbatim_desc error_message) Exceptions.Checkers (IssueType.starvation, Localise.verbatim_desc error_message)
in in
let first_trace = List.rev (make_loc_trace current_pname 1 current_loc current_elem) in let first_trace = List.rev (make_loc_trace current_pname 1 current_elem) in
let second_trace = make_loc_trace endpoint_pname 2 endpoint_loc endpoint_elem in let second_trace = make_loc_trace endpoint_pname 2 endpoint_elem in
let ltr = List.rev_append first_trace second_trace in let ltr = List.rev_append first_trace second_trace in
log_issue current_pname current_loc ltr exn log_issue current_pname current_loc ltr exn
| _ -> | _ ->
@ -279,13 +278,14 @@ let report_blocks_on_main_thread get_proc_desc tenv current_pdesc summary =
match eventually with match eventually with
| {LockEvent.event= LockEvent.MayBlock _} -> | {LockEvent.event= LockEvent.MayBlock _} ->
let error_message = let error_message =
Format.asprintf "UI thread method may block; %a" LockEvent.pp_event Format.asprintf "UI thread method %a may block; %a"
eventually.LockEvent.event (MF.wrap_monospaced Typ.Procname.pp)
current_pname LockEvent.pp_event eventually.LockEvent.event
in in
let exn = let exn =
Exceptions.Checkers (IssueType.starvation, Localise.verbatim_desc error_message) Exceptions.Checkers (IssueType.starvation, Localise.verbatim_desc error_message)
in in
let ltr = make_trace_with_header elem current_loc current_pname in let ltr = make_trace_with_header elem current_pname in
log_issue current_pname current_loc ltr exn log_issue current_pname current_loc ltr exn
| {LockEvent.event= LockEvent.LockAcquire endpoint_lock} -> | {LockEvent.event= LockEvent.LockAcquire endpoint_lock} ->
match LockIdentity.owner_class endpoint_lock with match LockIdentity.owner_class endpoint_lock with
@ -294,30 +294,26 @@ let report_blocks_on_main_thread get_proc_desc tenv current_pdesc summary =
| Some endpoint_class -> | Some endpoint_class ->
(* get the class of the root variable of the lock in the endpoint event (* get the class of the root variable of the lock in the endpoint event
and retrieve all the summaries of the methods of that class *) and retrieve all the summaries of the methods of that class *)
let endpoint_summaries = let endpoint_summaries = get_summaries_of_methods_in_class tenv endpoint_class in
get_summaries_of_methods_in_class get_proc_desc tenv current_pdesc endpoint_class
in
(* for each summary related to the endpoint, analyse and report on its pairs *) (* for each summary related to the endpoint, analyse and report on its pairs *)
List.iter endpoint_summaries ~f:(fun (endpoint_pdesc, (summary, main)) -> List.iter endpoint_summaries ~f:(fun (endpoint_pname, (summary, main)) ->
(* skip methods known to run on ui thread, as they cannot run in parallel to us *) (* skip methods known to run on ui thread, as they cannot run in parallel to us *)
if main then () if main then ()
else else
let endpoint_loc = Procdesc.get_loc endpoint_pdesc in
let endpoint_pname = Procdesc.get_proc_name endpoint_pdesc in
LockOrderDomain.iter LockOrderDomain.iter
(report_remote_block elem endpoint_lock endpoint_pname endpoint_loc) (report_remote_block elem endpoint_lock endpoint_pname)
summary ) summary )
in in
LockOrderDomain.iter report_on_current_elem summary LockOrderDomain.iter report_on_current_elem summary
let reporting {Callbacks.procedures; get_proc_desc; exe_env} = let reporting {Callbacks.procedures; exe_env} =
let report_procedure (tenv, proc_desc) = let report_procedure (tenv, proc_desc) =
die_if_not_java proc_desc ; die_if_not_java proc_desc ;
Payload.read proc_desc (Procdesc.get_proc_name proc_desc) Payload.read proc_desc (Procdesc.get_proc_name proc_desc)
|> Option.iter ~f:(fun ((s, main) as summary) -> |> Option.iter ~f:(fun ((s, main) as summary) ->
report_deadlocks get_proc_desc tenv proc_desc summary ; report_deadlocks tenv proc_desc summary ;
if main then report_blocks_on_main_thread get_proc_desc tenv proc_desc s ) if main then report_blocks_on_main_thread tenv proc_desc s )
in in
List.iter procedures ~f:report_procedure ; List.iter procedures ~f:report_procedure ;
let sourcefile = exe_env.Exe_env.source_file in let sourcefile = exe_env.Exe_env.source_file in

@ -1,29 +1,29 @@
codetoanalyze/java/starvation/AccMgr.java, void AccMgr.lockOnUiThreadBad(), 26, STARVATION, ERROR, [[Trace 1] void AccMgr.lockOnUiThreadBad(),locks `this.AccMgr.lock` in class `AccMgr*`,[Trace 2] void AccMgr.setUserDataUnderLock(),locks `this.AccMgr.lock` in class `AccMgr*`,calls void AccountManager.setUserData(Account,String,String) from void AccMgr.setUserDataUnderLock()] codetoanalyze/java/starvation/AccMgr.java, void AccMgr.lockOnUiThreadBad(), 26, STARVATION, ERROR, [[Trace 1] `void AccMgr.lockOnUiThreadBad()`,locks `this.AccMgr.lock` in class `AccMgr*`,[Trace 2] `void AccMgr.setUserDataUnderLock()`,locks `this.AccMgr.lock` in class `AccMgr*`,calls void AccountManager.setUserData(Account,String,String) from void AccMgr.setUserDataUnderLock()]
codetoanalyze/java/starvation/AccMgr.java, void AccMgr.onUiThreadBad(), 21, STARVATION, ERROR, [ void AccMgr.onUiThreadBad(),calls void AccountManager.setUserData(Account,String,String) from void AccMgr.onUiThreadBad()] codetoanalyze/java/starvation/AccMgr.java, void AccMgr.onUiThreadBad(), 21, STARVATION, ERROR, [ `void AccMgr.onUiThreadBad()`,calls void AccountManager.setUserData(Account,String,String) from void AccMgr.onUiThreadBad()]
codetoanalyze/java/starvation/AsyncTaskGet.java, void AsyncTaskGet.lockOnUiThreadBad(), 32, STARVATION, ERROR, [[Trace 1] void AsyncTaskGet.lockOnUiThreadBad(),locks `this.AsyncTaskGet.lock` in class `AsyncTaskGet*`,[Trace 2] void AsyncTaskGet.taskGetUnderLock(),locks `this.AsyncTaskGet.lock` in class `AsyncTaskGet*`,calls Object AsyncTask.get() from void AsyncTaskGet.taskGetUnderLock()] codetoanalyze/java/starvation/AsyncTaskGet.java, void AsyncTaskGet.lockOnUiThreadBad(), 32, STARVATION, ERROR, [[Trace 1] `void AsyncTaskGet.lockOnUiThreadBad()`,locks `this.AsyncTaskGet.lock` in class `AsyncTaskGet*`,[Trace 2] `void AsyncTaskGet.taskGetUnderLock()`,locks `this.AsyncTaskGet.lock` in class `AsyncTaskGet*`,calls Object AsyncTask.get() from void AsyncTaskGet.taskGetUnderLock()]
codetoanalyze/java/starvation/AsyncTaskGet.java, void AsyncTaskGet.taskGetOnUiThreadBad(), 21, STARVATION, ERROR, [ void AsyncTaskGet.taskGetOnUiThreadBad(),calls Object AsyncTask.get() from void AsyncTaskGet.taskGetOnUiThreadBad()] codetoanalyze/java/starvation/AsyncTaskGet.java, void AsyncTaskGet.taskGetOnUiThreadBad(), 21, STARVATION, ERROR, [ `void AsyncTaskGet.taskGetOnUiThreadBad()`,calls Object AsyncTask.get() from void AsyncTaskGet.taskGetOnUiThreadBad()]
codetoanalyze/java/starvation/Binders.java, void Binders.annotationBad(), 36, STARVATION, ERROR, [ void Binders.annotationBad(),Method call: void Binders.doTransact(),calls boolean Binder.transact(int,Parcel,Parcel,int) from void Binders.doTransact()] codetoanalyze/java/starvation/Binders.java, void Binders.annotationBad(), 36, STARVATION, ERROR, [ `void Binders.annotationBad()`,Method call: void Binders.doTransact(),calls boolean Binder.transact(int,Parcel,Parcel,int) from void Binders.doTransact()]
codetoanalyze/java/starvation/Binders.java, void Binders.interBad(), 25, STARVATION, ERROR, [ void Binders.interBad(),calls boolean Binder.transact(int,Parcel,Parcel,int) from void Binders.interBad()] codetoanalyze/java/starvation/Binders.java, void Binders.interBad(), 25, STARVATION, ERROR, [ `void Binders.interBad()`,calls boolean Binder.transact(int,Parcel,Parcel,int) from void Binders.interBad()]
codetoanalyze/java/starvation/Binders.java, void Binders.intraBad(), 30, STARVATION, ERROR, [ void Binders.intraBad(),Method call: void Binders.doTransact(),calls boolean Binder.transact(int,Parcel,Parcel,int) from void Binders.doTransact()] codetoanalyze/java/starvation/Binders.java, void Binders.intraBad(), 30, STARVATION, ERROR, [ `void Binders.intraBad()`,Method call: void Binders.doTransact(),calls boolean Binder.transact(int,Parcel,Parcel,int) from void Binders.doTransact()]
codetoanalyze/java/starvation/Countdwn.java, void Countdwn.awaitOnMainByAnnotBad(), 22, STARVATION, ERROR, [ void Countdwn.awaitOnMainByAnnotBad(),calls void CountDownLatch.await() from void Countdwn.awaitOnMainByAnnotBad()] codetoanalyze/java/starvation/Countdwn.java, void Countdwn.awaitOnMainByAnnotBad(), 22, STARVATION, ERROR, [ `void Countdwn.awaitOnMainByAnnotBad()`,calls void CountDownLatch.await() from void Countdwn.awaitOnMainByAnnotBad()]
codetoanalyze/java/starvation/Countdwn.java, void Countdwn.awaitOnMainByCallBad(), 16, STARVATION, ERROR, [ void Countdwn.awaitOnMainByCallBad(),calls void CountDownLatch.await() from void Countdwn.awaitOnMainByCallBad()] codetoanalyze/java/starvation/Countdwn.java, void Countdwn.awaitOnMainByCallBad(), 16, STARVATION, ERROR, [ `void Countdwn.awaitOnMainByCallBad()`,calls void CountDownLatch.await() from void Countdwn.awaitOnMainByCallBad()]
codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getDirectBad(), 21, STARVATION, ERROR, [ void FutureGet.getDirectBad(),calls Object Future.get() from void FutureGet.getDirectBad()] codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getDirectBad(), 21, STARVATION, ERROR, [ `void FutureGet.getDirectBad()`,calls Object Future.get() from void FutureGet.getDirectBad()]
codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getIndirectBad(), 26, STARVATION, ERROR, [[Trace 1] void FutureGet.getIndirectBad(),locks `this.FutureGet.lock` in class `FutureGet*`,[Trace 2] void FutureGet.getUnderLock(),locks `this.FutureGet.lock` in class `FutureGet*`,calls Object Future.get() from void FutureGet.getUnderLock()] codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getIndirectBad(), 26, STARVATION, ERROR, [[Trace 1] `void FutureGet.getIndirectBad()`,locks `this.FutureGet.lock` in class `FutureGet*`,[Trace 2] `void FutureGet.getUnderLock()`,locks `this.FutureGet.lock` in class `FutureGet*`,calls Object Future.get() from void FutureGet.getUnderLock()]
codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getTimeout50000001MicroSecondsBad(), 76, STARVATION, ERROR, [ void FutureGet.getTimeout50000001MicroSecondsBad(),calls Object Future.get(long,TimeUnit) from void FutureGet.getTimeout50000001MicroSecondsBad()] codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getTimeout50000001MicroSecondsBad(), 76, STARVATION, ERROR, [ `void FutureGet.getTimeout50000001MicroSecondsBad()`,calls Object Future.get(long,TimeUnit) from void FutureGet.getTimeout50000001MicroSecondsBad()]
codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getTimeoutOneDayBad(), 41, STARVATION, ERROR, [ void FutureGet.getTimeoutOneDayBad(),calls Object Future.get(long,TimeUnit) from void FutureGet.getTimeoutOneDayBad()] codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getTimeoutOneDayBad(), 41, STARVATION, ERROR, [ `void FutureGet.getTimeoutOneDayBad()`,calls Object Future.get(long,TimeUnit) from void FutureGet.getTimeoutOneDayBad()]
codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getTimeoutOneHourBad(), 55, STARVATION, ERROR, [ void FutureGet.getTimeoutOneHourBad(),calls Object Future.get(long,TimeUnit) from void FutureGet.getTimeoutOneHourBad()] codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getTimeoutOneHourBad(), 55, STARVATION, ERROR, [ `void FutureGet.getTimeoutOneHourBad()`,calls Object Future.get(long,TimeUnit) from void FutureGet.getTimeoutOneHourBad()]
codetoanalyze/java/starvation/IndirectBlock.java, void IndirectBlock.takeExpensiveLockOnUiThreadBad(), 23, STARVATION, ERROR, [[Trace 1] void IndirectBlock.takeExpensiveLockOnUiThreadBad(),locks `this.IndirectBlock.expensiveLock` in class `IndirectBlock*`,[Trace 2] void IndirectBlock.doTransactUnderLock(),locks `this.IndirectBlock.expensiveLock` in class `IndirectBlock*`,calls boolean Binder.transact(int,Parcel,Parcel,int) from void IndirectBlock.doTransactUnderLock()] codetoanalyze/java/starvation/IndirectBlock.java, void IndirectBlock.takeExpensiveLockOnUiThreadBad(), 23, STARVATION, ERROR, [[Trace 1] `void IndirectBlock.takeExpensiveLockOnUiThreadBad()`,locks `this.IndirectBlock.expensiveLock` in class `IndirectBlock*`,[Trace 2] `void IndirectBlock.doTransactUnderLock()`,locks `this.IndirectBlock.expensiveLock` in class `IndirectBlock*`,calls boolean Binder.transact(int,Parcel,Parcel,int) from void IndirectBlock.doTransactUnderLock()]
codetoanalyze/java/starvation/IndirectBlock.java, void IndirectBlock.takeRemoteExpensiveLockOnUiThreadBad(IndirectInterproc), 34, STARVATION, ERROR, [[Trace 1] void IndirectBlock.takeRemoteExpensiveLockOnUiThreadBad(IndirectInterproc),Method call: void IndirectInterproc.takeLock(),locks `this` in class `IndirectInterproc*`,[Trace 2] void IndirectInterproc.doTransactUnderLock(Binder),locks `this` in class `IndirectInterproc*`,calls boolean Binder.transact(int,Parcel,Parcel,int) from void IndirectInterproc.doTransactUnderLock(Binder)] codetoanalyze/java/starvation/IndirectBlock.java, void IndirectBlock.takeRemoteExpensiveLockOnUiThreadBad(IndirectInterproc), 34, STARVATION, ERROR, [[Trace 1] `void IndirectBlock.takeRemoteExpensiveLockOnUiThreadBad(IndirectInterproc)`,Method call: void IndirectInterproc.takeLock(),locks `this` in class `IndirectInterproc*`,[Trace 2] `void IndirectInterproc.doTransactUnderLock(Binder)`,locks `this` in class `IndirectInterproc*`,calls boolean Binder.transact(int,Parcel,Parcel,int) from void IndirectInterproc.doTransactUnderLock(Binder)]
codetoanalyze/java/starvation/InnerClass.java, InnerClass$InnerClassA.<init>(InnerClass,Object), 49, DEADLOCK, ERROR, [[Trace 1] InnerClass$InnerClassA.<init>(InnerClass,Object),locks `this` in class `InnerClass$InnerClassA*`,Method call: void InnerClass.bar(),locks `this` in class `InnerClass*`,[Trace 2] void InnerClass.outerInnerBad(InnerClass$InnerClassA),locks `this` in class `InnerClass*`,Method call: void InnerClass$InnerClassA.baz(),locks `this` in class `InnerClass$InnerClassA*`] codetoanalyze/java/starvation/InnerClass.java, InnerClass$InnerClassA.<init>(InnerClass,Object), 49, DEADLOCK, ERROR, [[Trace 1] `InnerClass$InnerClassA.<init>(InnerClass,Object)`,locks `this` in class `InnerClass$InnerClassA*`,Method call: void InnerClass.bar(),locks `this` in class `InnerClass*`,[Trace 2] `void InnerClass.outerInnerBad(InnerClass$InnerClassA)`,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(), 36, DEADLOCK, ERROR, [[Trace 1] void InnerClass$InnerClassA.innerOuterBad(),locks `this` in class `InnerClass$InnerClassA*`,Method call: void InnerClass.bar(),locks `this` in class `InnerClass*`,[Trace 2] void InnerClass.outerInnerBad(InnerClass$InnerClassA),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(), 36, DEADLOCK, ERROR, [[Trace 1] `void InnerClass$InnerClassA.innerOuterBad()`,locks `this` in class `InnerClass$InnerClassA*`,Method call: void InnerClass.bar(),locks `this` in class `InnerClass*`,[Trace 2] `void InnerClass.outerInnerBad(InnerClass$InnerClassA)`,locks `this` in class `InnerClass*`,Method call: void InnerClass$InnerClassA.baz(),locks `this` in class `InnerClass$InnerClassA*`]
codetoanalyze/java/starvation/Interclass.java, void Interclass.interclass1Bad(InterclassA), 12, DEADLOCK, ERROR, [[Trace 1] void Interclass.interclass1Bad(InterclassA),locks `this` in class `Interclass*`,Method call: void InterclassA.interclass1Bad(),locks `this` in class `InterclassA*`,[Trace 2] void InterclassA.interclass2Bad(Interclass),locks `this` in class `InterclassA*`,Method call: void Interclass.interclass2Bad(),locks `this` in class `Interclass*`] codetoanalyze/java/starvation/Interclass.java, void Interclass.interclass1Bad(InterclassA), 12, DEADLOCK, ERROR, [[Trace 1] `void Interclass.interclass1Bad(InterclassA)`,locks `this` in class `Interclass*`,Method call: void InterclassA.interclass1Bad(),locks `this` in class `InterclassA*`,[Trace 2] `void InterclassA.interclass2Bad(Interclass)`,locks `this` in class `InterclassA*`,Method call: void Interclass.interclass2Bad(),locks `this` in class `Interclass*`]
codetoanalyze/java/starvation/Interproc.java, void Interproc.interproc1Bad(InterprocA), 11, DEADLOCK, ERROR, [[Trace 1] void Interproc.interproc1Bad(InterprocA),locks `this` in class `Interproc*`,Method call: void Interproc.interproc2Bad(InterprocA),locks `b` in class `InterprocA*`,[Trace 2] void InterprocA.interproc1Bad(Interproc),locks `this` in class `InterprocA*`,Method call: void InterprocA.interproc2Bad(Interproc),locks `d` in class `Interproc*`] codetoanalyze/java/starvation/Interproc.java, void Interproc.interproc1Bad(InterprocA), 11, DEADLOCK, ERROR, [[Trace 1] `void Interproc.interproc1Bad(InterprocA)`,locks `this` in class `Interproc*`,Method call: void Interproc.interproc2Bad(InterprocA),locks `b` in class `InterprocA*`,[Trace 2] `void InterprocA.interproc1Bad(Interproc)`,locks `this` in class `InterprocA*`,Method call: void InterprocA.interproc2Bad(Interproc),locks `d` in class `Interproc*`]
codetoanalyze/java/starvation/Intraproc.java, void Intraproc.intraBad(IntraprocA), 11, DEADLOCK, ERROR, [[Trace 1] void Intraproc.intraBad(IntraprocA),locks `this` in class `Intraproc*`,locks `o` in class `IntraprocA*`,[Trace 2] void IntraprocA.intraBad(Intraproc),locks `this` in class `IntraprocA*`,locks `o` in class `Intraproc*`] codetoanalyze/java/starvation/Intraproc.java, void Intraproc.intraBad(IntraprocA), 11, DEADLOCK, ERROR, [[Trace 1] `void Intraproc.intraBad(IntraprocA)`,locks `this` in class `Intraproc*`,locks `o` in class `IntraprocA*`,[Trace 2] `void IntraprocA.intraBad(Intraproc)`,locks `this` in class `IntraprocA*`,locks `o` in class `Intraproc*`]
codetoanalyze/java/starvation/JavaIO.java, void JavaIO.fileReadBad(), 32, STARVATION, ERROR, [ void JavaIO.fileReadBad(),Method call: int JavaIO.doFileRead(),calls int InputStreamReader.read() from int JavaIO.doFileRead()] codetoanalyze/java/starvation/JavaIO.java, void JavaIO.fileReadBad(), 32, STARVATION, ERROR, [ `void JavaIO.fileReadBad()`,Method call: int JavaIO.doFileRead(),calls int InputStreamReader.read() from int JavaIO.doFileRead()]
codetoanalyze/java/starvation/JavaIO.java, void JavaIO.streamReadBad(), 37, STARVATION, ERROR, [ void JavaIO.streamReadBad(),Method call: String JavaIO.doStreamRead(),calls String DataInputStream.readUTF() from String JavaIO.doStreamRead()] codetoanalyze/java/starvation/JavaIO.java, void JavaIO.streamReadBad(), 37, STARVATION, ERROR, [ `void JavaIO.streamReadBad()`,Method call: String JavaIO.doStreamRead(),calls String DataInputStream.readUTF() from String JavaIO.doStreamRead()]
codetoanalyze/java/starvation/LegacySync.java, Object LegacySync.onUiThreadOpBad(), 26, STARVATION, ERROR, [[Trace 1] Object LegacySync.onUiThreadOpBad(),locks `this.LegacySync.table` in class `LegacySync*`,[Trace 2] void LegacySync.notOnUiThreadSyncedBad(),locks `this.LegacySync.table` in class `LegacySync*`,calls Object Future.get() from void LegacySync.notOnUiThreadSyncedBad()] codetoanalyze/java/starvation/LegacySync.java, Object LegacySync.onUiThreadOpBad(), 26, STARVATION, ERROR, [[Trace 1] `Object LegacySync.onUiThreadOpBad()`,locks `this.LegacySync.table` in class `LegacySync*`,[Trace 2] `void LegacySync.notOnUiThreadSyncedBad()`,locks `this.LegacySync.table` in class `LegacySync*`,calls Object Future.get() from void LegacySync.notOnUiThreadSyncedBad()]
codetoanalyze/java/starvation/ServiceOnUIThread.java, IBinder ServiceOnUIThread.onBind(Intent), 20, STARVATION, ERROR, [ IBinder ServiceOnUIThread.onBind(Intent),Method call: void ServiceOnUIThread.transactBad(),calls boolean IBinder.transact(int,Parcel,Parcel,int) from void ServiceOnUIThread.transactBad()] codetoanalyze/java/starvation/ServiceOnUIThread.java, IBinder ServiceOnUIThread.onBind(Intent), 20, STARVATION, ERROR, [ `IBinder ServiceOnUIThread.onBind(Intent)`,Method call: void ServiceOnUIThread.transactBad(),calls boolean IBinder.transact(int,Parcel,Parcel,int) from void ServiceOnUIThread.transactBad()]
codetoanalyze/java/starvation/ServiceOnUIThread.java, void ServiceOnUIThread.transactBad(), 25, STARVATION, ERROR, [ void ServiceOnUIThread.transactBad(),calls boolean IBinder.transact(int,Parcel,Parcel,int) from void ServiceOnUIThread.transactBad()] codetoanalyze/java/starvation/ServiceOnUIThread.java, void ServiceOnUIThread.transactBad(), 25, STARVATION, ERROR, [ `void ServiceOnUIThread.transactBad()`,calls boolean IBinder.transact(int,Parcel,Parcel,int) from void ServiceOnUIThread.transactBad()]
codetoanalyze/java/starvation/StaticLock.java, void StaticLock.lockOtherClassOneWayBad(), 24, DEADLOCK, ERROR, [[Trace 1] void StaticLock.lockOtherClassOneWayBad(),locks `StaticLock$0` in class `java.lang.Class*`,locks `this` in class `StaticLock*`,[Trace 2] void StaticLock.lockOtherClassAnotherWayNad(),locks `this` in class `StaticLock*`,Method call: void StaticLock.staticSynced(),locks `StaticLock$0` in class `java.lang.Class*`] codetoanalyze/java/starvation/StaticLock.java, void StaticLock.lockOtherClassOneWayBad(), 24, DEADLOCK, ERROR, [[Trace 1] `void StaticLock.lockOtherClassOneWayBad()`,locks `StaticLock$0` in class `java.lang.Class*`,locks `this` in class `StaticLock*`,[Trace 2] `void StaticLock.lockOtherClassAnotherWayNad()`,locks `this` in class `StaticLock*`,Method call: void StaticLock.staticSynced(),locks `StaticLock$0` in class `java.lang.Class*`]
codetoanalyze/java/starvation/UIDeadlock.java, void UIDeadlock.onUIThreadBad(), 28, DEADLOCK, ERROR, [[Trace 1] void UIDeadlock.onUIThreadBad(),locks `this` in class `UIDeadlock*`,locks `this.UIDeadlock.lockB` in class `UIDeadlock*`,[Trace 2] void UIDeadlock.notOnUIThreadBad(),locks `this.UIDeadlock.lockB` in class `UIDeadlock*`,locks `this` in class `UIDeadlock*`] codetoanalyze/java/starvation/UIDeadlock.java, void UIDeadlock.onUIThreadBad(), 28, DEADLOCK, ERROR, [[Trace 1] `void UIDeadlock.onUIThreadBad()`,locks `this` in class `UIDeadlock*`,locks `this.UIDeadlock.lockB` in class `UIDeadlock*`,[Trace 2] `void UIDeadlock.notOnUIThreadBad()`,locks `this.UIDeadlock.lockB` in class `UIDeadlock*`,locks `this` in class `UIDeadlock*`]
codetoanalyze/java/starvation/VisDispFrame.java, void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad(), 19, STARVATION, ERROR, [ void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad(),calls void View.getWindowVisibleDisplayFrame(Rect) from void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad()] codetoanalyze/java/starvation/VisDispFrame.java, void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad(), 19, STARVATION, ERROR, [ `void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad()`,calls void View.getWindowVisibleDisplayFrame(Rect) from void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad()]

Loading…
Cancel
Save