From 5e8b118151fa8fd67b1f8fd0e3b70da49d8ba5bc Mon Sep 17 00:00:00 2001 From: Nikos Gorogiannis Date: Tue, 22 May 2018 06:52:49 -0700 Subject: [PATCH] [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 --- infer/src/base/IssueType.ml | 2 +- infer/src/concurrency/starvation.ml | 84 +++++++++---------- .../codetoanalyze/java/starvation/issues.exp | 58 ++++++------- 3 files changed, 70 insertions(+), 74 deletions(-) diff --git a/infer/src/base/IssueType.ml b/infer/src/base/IssueType.ml index 6102a836d..83aa416e6 100644 --- a/infer/src/base/IssueType.ml +++ b/infer/src/base/IssueType.ml @@ -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 starvation = from_string "STARVATION" +let starvation = from_string "STARVATION" ~hum:"UI Thread Starvation" let static_initialization_order_fiasco = from_string "STATIC_INITIALIZATION_ORDER_FIASCO" diff --git a/infer/src/concurrency/starvation.ml b/infer/src/concurrency/starvation.ml index 857cd895c..8064ce3c9 100644 --- a/infer/src/concurrency/starvation.ml +++ b/infer/src/concurrency/starvation.ml @@ -9,6 +9,7 @@ open! IStd module F = Format module L = Logging +module MF = MarkupFormatter 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 ) -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_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 -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 - 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 methods = Option.value_map tstruct_opt ~default:[] ~f:(fun tstruct -> tstruct.Typ.Struct.methods) in - let pdescs = List.rev_filter_map methods ~f:get_proc_desc in - let get_summary callee_pdesc = - Payload.read current_pdesc (Procdesc.get_proc_name callee_pdesc) - |> Option.map ~f:(fun summary -> (callee_pdesc, summary)) - in - List.rev_filter_map pdescs ~f:get_summary + let summaries = List.rev_filter_map methods ~f:Ondemand.analyze_proc_name in + List.rev_filter_map summaries ~f:(fun sum -> + Option.map sum.Summary.payloads.Payloads.starvation ~f:(fun p -> + (Summary.get_proc_name sum, p) ) ) 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. 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. *) -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 current_loc = Procdesc.get_loc 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 LockOrder.may_deadlock 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 = Format.asprintf "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 in let exn = Exceptions.Checkers (IssueType.deadlock, Localise.verbatim_desc error_message) in - let first_trace = List.rev (make_loc_trace current_pname 1 current_loc current_elem) in - let second_trace = make_loc_trace endpoint_pname 2 endpoint_loc 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 elem in let ltr = List.rev_append first_trace second_trace in 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 -> (* 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 *) - let endpoint_summaries = - get_summaries_of_methods_in_class get_proc_desc tenv current_pdesc endpoint_class - in + let endpoint_summaries = get_summaries_of_methods_in_class tenv endpoint_class in (* 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 - let endpoint_loc = Procdesc.get_loc endpoint_pdesc in - let endpoint_pname = Procdesc.get_proc_name endpoint_pdesc in - LockOrderDomain.iter - (report_endpoint_elem elem endpoint_pname endpoint_loc) - summary ) + LockOrderDomain.iter (report_endpoint_elem elem endpoint_pname) summary ) in 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 current_loc = Procdesc.get_loc 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 | { LockOrder.first= Some {LockEvent.event= LockEvent.LockAcquire lock} ; eventually= {LockEvent.event= LockEvent.MayBlock block_descr} } when LockIdentity.equal current_lock lock -> let error_message = - Format.asprintf "UI thread %a, which may be held by another thread which %s" - LockIdentity.pp lock block_descr + Format.asprintf "UI thread method %a %a, which may be held by another thread which %s" + (MF.wrap_monospaced Typ.Procname.pp) + current_pname LockIdentity.pp lock block_descr in let exn = Exceptions.Checkers (IssueType.starvation, Localise.verbatim_desc error_message) in - let first_trace = List.rev (make_loc_trace current_pname 1 current_loc current_elem) in - let second_trace = make_loc_trace endpoint_pname 2 endpoint_loc endpoint_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_elem in let ltr = List.rev_append first_trace second_trace in 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 | {LockEvent.event= LockEvent.MayBlock _} -> let error_message = - Format.asprintf "UI thread method may block; %a" LockEvent.pp_event - eventually.LockEvent.event + Format.asprintf "UI thread method %a may block; %a" + (MF.wrap_monospaced Typ.Procname.pp) + current_pname LockEvent.pp_event eventually.LockEvent.event in let exn = Exceptions.Checkers (IssueType.starvation, Localise.verbatim_desc error_message) 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 | {LockEvent.event= LockEvent.LockAcquire endpoint_lock} -> 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 -> (* 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 *) - let endpoint_summaries = - get_summaries_of_methods_in_class get_proc_desc tenv current_pdesc endpoint_class - in + let endpoint_summaries = get_summaries_of_methods_in_class tenv endpoint_class in (* 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 *) if main then () else - let endpoint_loc = Procdesc.get_loc endpoint_pdesc in - let endpoint_pname = Procdesc.get_proc_name endpoint_pdesc in LockOrderDomain.iter - (report_remote_block elem endpoint_lock endpoint_pname endpoint_loc) + (report_remote_block elem endpoint_lock endpoint_pname) summary ) in 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) = die_if_not_java proc_desc ; Payload.read proc_desc (Procdesc.get_proc_name proc_desc) |> Option.iter ~f:(fun ((s, main) as summary) -> - report_deadlocks get_proc_desc tenv proc_desc summary ; - if main then report_blocks_on_main_thread get_proc_desc tenv proc_desc s ) + report_deadlocks tenv proc_desc summary ; + if main then report_blocks_on_main_thread tenv proc_desc s ) in List.iter procedures ~f:report_procedure ; let sourcefile = exe_env.Exe_env.source_file in diff --git a/infer/tests/codetoanalyze/java/starvation/issues.exp b/infer/tests/codetoanalyze/java/starvation/issues.exp index 96b785d4e..f8a62d7b9 100644 --- a/infer/tests/codetoanalyze/java/starvation/issues.exp +++ b/infer/tests/codetoanalyze/java/starvation/issues.exp @@ -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.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.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.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/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/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.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.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.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.(InnerClass,Object), 49, DEADLOCK, ERROR, [[Trace 1] InnerClass$InnerClassA.(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/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/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.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/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/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/VisDispFrame.java, void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad(), 19, STARVATION, ERROR, [ void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad(),calls void View.getWindowVisibleDisplayFrame(Rect) from void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad()] +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/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/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.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.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.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.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/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/InnerClass.java, InnerClass$InnerClassA.(InnerClass,Object), 49, DEADLOCK, ERROR, [[Trace 1] `InnerClass$InnerClassA.(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/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/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.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/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/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/VisDispFrame.java, void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad(), 19, STARVATION, ERROR, [ `void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad()`,calls void View.getWindowVisibleDisplayFrame(Rect) from void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad()]