From 538bcd9135bd0c50da8ae15e79ba94225bad6f51 Mon Sep 17 00:00:00 2001 From: Nikos Gorogiannis Date: Mon, 7 May 2018 04:59:48 -0700 Subject: [PATCH] [starvation] store issues to issue-logs like linters do Reviewed By: jeremydubreil Differential Revision: D7876329 fbshipit-source-id: 6572f3a --- infer/src/IR/IssueLog.ml | 21 +++++--- infer/src/IR/IssueLog.mli | 16 +++--- infer/src/backend/InferPrint.ml | 7 ++- infer/src/backend/callbacks.ml | 6 ++- infer/src/backend/callbacks.mli | 4 +- infer/src/base/Config.ml | 2 + infer/src/base/Config.mli | 2 + infer/src/clang/cFrontend_checkers_main.ml | 12 +---- infer/src/clang/cFrontend_errors.ml | 2 +- infer/src/concurrency/starvation.ml | 18 ++++--- .../codetoanalyze/java/starvation/issues.exp | 50 +++++++++---------- 11 files changed, 75 insertions(+), 65 deletions(-) diff --git a/infer/src/IR/IssueLog.ml b/infer/src/IR/IssueLog.ml index bae1fc294..0c8a7cd08 100644 --- a/infer/src/IR/IssueLog.ml +++ b/infer/src/IR/IssueLog.ml @@ -13,11 +13,7 @@ open! IStd let errLogMap = ref Typ.Procname.Map.empty -let exist_issues () = not (Typ.Procname.Map.is_empty !errLogMap) - -let get_map () = !errLogMap - -let get_err_log procname = +let get_errlog procname = try Typ.Procname.Map.find procname !errLogMap with Caml.Not_found -> let errlog = Errlog.empty () in errLogMap := Typ.Procname.Map.add procname errlog !errLogMap ; @@ -28,8 +24,19 @@ let issues_serializer : Errlog.t Typ.Procname.Map.t Serialization.serializer = Serialization.create_serializer Serialization.Key.issues -(** Save issues to a file *) -let store filename = Serialization.write_to_file issues_serializer filename ~data:!errLogMap +let iter f = Typ.Procname.Map.iter f !errLogMap + +let store directory source_file = + if not (Typ.Procname.Map.is_empty !errLogMap) then ( + let abbrev_source_file = DB.source_file_encoding source_file in + let issues_dir = Config.results_dir ^/ directory in + Utils.create_dir issues_dir ; + let filename = + DB.filename_from_string (Filename.concat issues_dir (abbrev_source_file ^ ".issue")) + in + Serialization.write_to_file issues_serializer filename ~data:!errLogMap ) + else () + (** Load issues from the given file *) let load_issues issues_file = Serialization.read_from_file issues_serializer issues_file diff --git a/infer/src/IR/IssueLog.mli b/infer/src/IR/IssueLog.mli index ef2acb4b8..c28630259 100644 --- a/infer/src/IR/IssueLog.mli +++ b/infer/src/IR/IssueLog.mli @@ -11,17 +11,17 @@ open! IStd (** Module to store a map from procnames to error logs. Starts with an empty map. *) -val get_map : unit -> Errlog.t Typ.Procname.Map.t +val iter : (Typ.Procname.t -> Errlog.t -> unit) -> unit +(** iterate a function on map contents *) -val exist_issues : unit -> bool - -val get_err_log : Typ.Procname.t -> Errlog.t -(** Get the error log for a given procname. If not present, then add the association from +val get_errlog : Typ.Procname.t -> Errlog.t +(** Get the error log for a given procname. If not present, then add the association from procname to an empty error log and return the latter. *) -val store : DB.filename -> unit -(** Store map to a file *) +val store : string -> SourceFile.t -> unit +(** If there are any issues in the log, [store dirname filename] stores map to [infer-out/dirname/filename]. + Otherwise, no file is written. *) val load : string -> unit -(** Reset the issue map first, then walk the directory given as argument and merge all +(** [load directory] resets the issue map first, then walks [infer-out/directory], merging all maps stored in the found files into the current map. *) diff --git a/infer/src/backend/InferPrint.ml b/infer/src/backend/InferPrint.ml index 34c2a5219..24c7963a0 100644 --- a/infer/src/backend/InferPrint.ml +++ b/infer/src/backend/InferPrint.ml @@ -967,10 +967,9 @@ let pp_summary_and_issues formats_by_report_kind issue_formats = issue_formats ) (Issue.sort_filter_issues !all_issues) ; if Config.precondition_stats then PreconditionStats.pp_stats () ; - IssueLog.load Config.lint_issues_dir_name ; - Typ.Procname.Map.iter - (pp_lint_issues filters formats_by_report_kind linereader) - (IssueLog.get_map ()) ; + List.iter [Config.lint_issues_dir_name; Config.starvation_issues_dir_name] ~f:(fun dir_name -> + IssueLog.load dir_name ; + IssueLog.iter (pp_lint_issues filters formats_by_report_kind linereader) ) ; finalize_and_close_files formats_by_report_kind stats diff --git a/infer/src/backend/callbacks.ml b/infer/src/backend/callbacks.ml index f5c51ecfb..08eb32a1f 100644 --- a/infer/src/backend/callbacks.ml +++ b/infer/src/backend/callbacks.ml @@ -23,7 +23,9 @@ type proc_callback_args = type proc_callback_t = proc_callback_args -> Specs.summary type cluster_callback_args = - {procedures: (Tenv.t * Procdesc.t) list; get_proc_desc: Typ.Procname.t -> Procdesc.t option} + { procedures: (Tenv.t * Procdesc.t) list + ; get_proc_desc: Typ.Procname.t -> Procdesc.t option + ; exe_env: Exe_env.t } type cluster_callback_t = cluster_callback_args -> unit @@ -78,7 +80,7 @@ let iterate_procedure_callbacks get_proc_desc exe_env summary proc_desc = let iterate_cluster_callbacks all_procs exe_env get_proc_desc = if !cluster_callbacks <> [] then let procedures = List.filter_map ~f:(get_procedure_definition exe_env) all_procs in - let environment = {procedures; get_proc_desc} in + let environment = {procedures; get_proc_desc; exe_env} in let language_matches language = match procedures with | (_, pdesc) :: _ -> diff --git a/infer/src/backend/callbacks.mli b/infer/src/backend/callbacks.mli index 64f0cdd7d..7a0051854 100644 --- a/infer/src/backend/callbacks.mli +++ b/infer/src/backend/callbacks.mli @@ -27,7 +27,9 @@ type proc_callback_args = type proc_callback_t = proc_callback_args -> Specs.summary type cluster_callback_args = - {procedures: (Tenv.t * Procdesc.t) list; get_proc_desc: Typ.Procname.t -> Procdesc.t option} + { procedures: (Tenv.t * Procdesc.t) list + ; get_proc_desc: Typ.Procname.t -> Procdesc.t option + ; exe_env: Exe_env.t } type cluster_callback_t = cluster_callback_args -> unit diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 666dfea6a..00c21f03f 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -283,6 +283,8 @@ let specs_dir_name = "specs" let specs_files_suffix = ".specs" +let starvation_issues_dir_name = "starvation_issues" + (** Enable detailed tracing information during array abstraction *) let trace_absarray = false diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index d23f1f09a..1b2eca208 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -229,6 +229,8 @@ val specs_dir_name : string val specs_files_suffix : string +val starvation_issues_dir_name : string + val trace_absarray : bool val undo_join : bool diff --git a/infer/src/clang/cFrontend_checkers_main.ml b/infer/src/clang/cFrontend_checkers_main.ml index 533acc600..417c86699 100644 --- a/infer/src/clang/cFrontend_checkers_main.ml +++ b/infer/src/clang/cFrontend_checkers_main.ml @@ -365,16 +365,6 @@ let context_with_ck_set context decl_list = if is_ck then {context with CLintersContext.is_ck_translation_unit= true} else context -let store_issues source_file = - let abbrev_source_file = DB.source_file_encoding source_file in - let lint_issues_dir = Config.results_dir ^/ Config.lint_issues_dir_name in - Utils.create_dir lint_issues_dir ; - let lint_issues_file = - DB.filename_from_string (Filename.concat lint_issues_dir (abbrev_source_file ^ ".issue")) - in - IssueLog.store lint_issues_file - - let find_linters_files () = List.concat_map ~f:(fun folder -> Utils.find_files ~path:folder ~extension:".al") @@ -412,7 +402,7 @@ let do_frontend_checks (trans_unit_ctx: CFrontend_config.translation_unit_contex let active_map : Tableaux.context_linter_map = Tableaux.init_active_map () in CFrontend_errors.invoke_set_of_checkers_on_node context (Ctl_parser_types.Decl ast) ; List.iter ~f:(do_frontend_checks_decl context active_map) allowed_decls ; - if IssueLog.exist_issues () then store_issues source_file ; + IssueLog.store Config.lint_issues_dir_name source_file ; L.(debug Linters Medium) "End linting file %a@\n" SourceFile.pp source_file ; CTL.save_dotty_when_in_debug_mode trans_unit_ctx.CFrontend_config.source_file (*if CFrontend_config.tableaux_evaluation then ( diff --git a/infer/src/clang/cFrontend_errors.ml b/infer/src/clang/cFrontend_errors.ml index 0ccbb9e58..daa2d870c 100644 --- a/infer/src/clang/cFrontend_errors.ml +++ b/infer/src/clang/cFrontend_errors.ml @@ -445,7 +445,7 @@ let log_frontend_issue ~is_cpp method_decl_opt (node: Ctl_parser_types.ast_node) | None -> Typ.Procname.Linters_dummy_method in - let errlog = IssueLog.get_err_log procname in + let errlog = IssueLog.get_errlog procname in let err_desc = Errdesc.explain_frontend_warning issue_desc.description issue_desc.suggestion issue_desc.loc in diff --git a/infer/src/concurrency/starvation.ml b/infer/src/concurrency/starvation.ml index e409fb80a..e63e56c2c 100644 --- a/infer/src/concurrency/starvation.ml +++ b/infer/src/concurrency/starvation.ml @@ -156,6 +156,11 @@ let get_summaries_of_methods_in_class get_proc_desc tenv current_pdesc clazz = List.rev_filter_map pdescs ~f:(get_summary current_pdesc) +let log_issue current_pname current_loc ltr exn = + let errlog = IssueLog.get_errlog current_pname in + Reporting.log_issue_from_errlog current_pname Exceptions.Kerror errlog ~loc:current_loc ~ltr exn + + (* Note about how many times we report a deadlock: normally twice, at each trace starting point. Due to the fact we look for deadlocks in the summaries of the class at the root of a path, this will fail when (a) the lock is of class type (ie as used in static sync methods), because @@ -184,8 +189,7 @@ let report_deadlocks get_proc_desc tenv current_pdesc (summary, _) = 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 ltr = List.rev_append first_trace second_trace in - Reporting.log_error_deprecated ~store_summary:true current_pname ~loc:current_loc ~ltr - exn + log_issue current_pname current_loc ltr exn | _, _ -> () in @@ -232,7 +236,7 @@ let report_blocks_on_main_thread get_proc_desc tenv current_pdesc summary = 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 ltr = List.rev_append first_trace second_trace in - Reporting.log_error_deprecated ~store_summary:true current_pname ~loc:current_loc ~ltr exn + log_issue current_pname current_loc ltr exn | _ -> () in @@ -247,7 +251,7 @@ let report_blocks_on_main_thread get_proc_desc tenv current_pdesc summary = Exceptions.Checkers (IssueType.starvation, Localise.verbatim_desc error_message) in let ltr = make_trace_with_header elem current_loc current_pname in - Reporting.log_error_deprecated ~store_summary:true current_pname ~loc:current_loc ~ltr exn + log_issue current_pname current_loc ltr exn | {LockEvent.event= LockEvent.LockAcquire endpoint_lock} -> match LockIdentity.owner_class endpoint_lock with | None -> @@ -272,11 +276,13 @@ let report_blocks_on_main_thread get_proc_desc tenv current_pdesc summary = LockOrderDomain.iter report_on_current_elem summary -let reporting {Callbacks.procedures; get_proc_desc} = +let reporting {Callbacks.procedures; get_proc_desc; exe_env} = let report_procedure (tenv, proc_desc) = Summary.read_summary 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 ) in - List.iter procedures ~f:report_procedure + List.iter procedures ~f:report_procedure ; + let sourcefile = exe_env.Exe_env.source_file in + IssueLog.store Config.starvation_issues_dir_name sourcefile diff --git a/infer/tests/codetoanalyze/java/starvation/issues.exp b/infer/tests/codetoanalyze/java/starvation/issues.exp index e6ae72f39..62acb039a 100644 --- a/infer/tests/codetoanalyze/java/starvation/issues.exp +++ b/infer/tests/codetoanalyze/java/starvation/issues.exp @@ -1,25 +1,25 @@ -codetoanalyze/java/starvation/AccMgr.java, void AccMgr.lockOnUiThreadBad(), 0, 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(), 0, STARVATION, ERROR, [ void AccMgr.onUiThreadBad(),calls void AccountManager.setUserData(Account,String,String) from void AccMgr.onUiThreadBad()] -codetoanalyze/java/starvation/Binders.java, void Binders.annotationBad(), 0, 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(), 0, 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(), 0, 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(), 0, STARVATION, ERROR, [ void Countdwn.awaitOnMainByAnnotBad(),calls void CountDownLatch.await() from void Countdwn.awaitOnMainByAnnotBad()] -codetoanalyze/java/starvation/Countdwn.java, void Countdwn.awaitOnMainByCallBad(), 0, STARVATION, ERROR, [ void Countdwn.awaitOnMainByCallBad(),calls void CountDownLatch.await() from void Countdwn.awaitOnMainByCallBad()] -codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getDirectBad(), 0, STARVATION, ERROR, [ void FutureGet.getDirectBad(),calls Object Future.get() from void FutureGet.getDirectBad()] -codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getIndirectBad(), 0, 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/IndirectBlock.java, void IndirectBlock.takeExpensiveLockOnUiThreadBad(), 0, 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), 0, 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), 0, STARVATION, 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(), 0, STARVATION, 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.outerInnerBad(InnerClass$InnerClassA), 0, STARVATION, ERROR, [[Trace 1] void InnerClass.outerInnerBad(InnerClass$InnerClassA),locks `this` in class `InnerClass*`,Method call: void InnerClass$InnerClassA.baz(),locks `this` in class `InnerClass$InnerClassA*`,[Trace 2] void InnerClass$InnerClassA.innerOuterBad(),locks `this` in class `InnerClass$InnerClassA*`,Method call: void InnerClass.bar(),locks `this` in class `InnerClass*`] -codetoanalyze/java/starvation/InnerClass.java, void InnerClass.outerInnerBad(InnerClass$InnerClassA), 0, STARVATION, ERROR, [[Trace 1] void InnerClass.outerInnerBad(InnerClass$InnerClassA),locks `this` in class `InnerClass*`,Method call: void InnerClass$InnerClassA.baz(),locks `this` in class `InnerClass$InnerClassA*`,[Trace 2] InnerClass$InnerClassA.(InnerClass,Object),locks `this` in class `InnerClass$InnerClassA*`,Method call: void InnerClass.bar(),locks `this` in class `InnerClass*`] -codetoanalyze/java/starvation/Interclass.java, void Interclass.interclass1Bad(InterclassA), 0, STARVATION, 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 InterclassA.interclass2Bad(Interclass), 0, STARVATION, ERROR, [[Trace 1] void InterclassA.interclass2Bad(Interclass),locks `this` in class `InterclassA*`,Method call: void Interclass.interclass2Bad(),locks `this` in class `Interclass*`,[Trace 2] void Interclass.interclass1Bad(InterclassA),locks `this` in class `Interclass*`,Method call: void InterclassA.interclass1Bad(),locks `this` in class `InterclassA*`] -codetoanalyze/java/starvation/Interproc.java, void Interproc.interproc1Bad(InterprocA), 0, STARVATION, 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 InterprocA.interproc1Bad(Interproc), 0, STARVATION, ERROR, [[Trace 1] void InterprocA.interproc1Bad(Interproc),locks `this` in class `InterprocA*`,Method call: void InterprocA.interproc2Bad(Interproc),locks `d` in class `Interproc*`,[Trace 2] void Interproc.interproc1Bad(InterprocA),locks `this` in class `Interproc*`,Method call: void Interproc.interproc2Bad(InterprocA),locks `b` in class `InterprocA*`] -codetoanalyze/java/starvation/Intraproc.java, void Intraproc.intraBad(IntraprocA), 0, STARVATION, 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 IntraprocA.intraBad(Intraproc), 0, STARVATION, ERROR, [[Trace 1] void IntraprocA.intraBad(Intraproc),locks `this` in class `IntraprocA*`,locks `o` in class `Intraproc*`,[Trace 2] void Intraproc.intraBad(IntraprocA),locks `this` in class `Intraproc*`,locks `o` in class `IntraprocA*`] -codetoanalyze/java/starvation/JavaIO.java, void JavaIO.fileReadBad(), 0, 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(), 0, STARVATION, ERROR, [ void JavaIO.streamReadBad(),Method call: String JavaIO.doStreamRead(),calls String DataInputStream.readUTF() from String JavaIO.doStreamRead()] -codetoanalyze/java/starvation/StaticLock.java, void StaticLock.lockOtherClassOneWayBad(), 0, STARVATION, 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/VisDispFrame.java, void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad(), 0, 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/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(), 19, STARVATION, ERROR, [ void FutureGet.getDirectBad(),calls Object Future.get() from void FutureGet.getDirectBad()] +codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getIndirectBad(), 24, 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/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, STARVATION, 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, STARVATION, 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.outerInnerBad(InnerClass$InnerClassA), 19, STARVATION, ERROR, [[Trace 1] void InnerClass.outerInnerBad(InnerClass$InnerClassA),locks `this` in class `InnerClass*`,Method call: void InnerClass$InnerClassA.baz(),locks `this` in class `InnerClass$InnerClassA*`,[Trace 2] void InnerClass$InnerClassA.innerOuterBad(),locks `this` in class `InnerClass$InnerClassA*`,Method call: void InnerClass.bar(),locks `this` in class `InnerClass*`] +codetoanalyze/java/starvation/InnerClass.java, void InnerClass.outerInnerBad(InnerClass$InnerClassA), 19, STARVATION, ERROR, [[Trace 1] void InnerClass.outerInnerBad(InnerClass$InnerClassA),locks `this` in class `InnerClass*`,Method call: void InnerClass$InnerClassA.baz(),locks `this` in class `InnerClass$InnerClassA*`,[Trace 2] InnerClass$InnerClassA.(InnerClass,Object),locks `this` in class `InnerClass$InnerClassA*`,Method call: void InnerClass.bar(),locks `this` in class `InnerClass*`] +codetoanalyze/java/starvation/Interclass.java, void Interclass.interclass1Bad(InterclassA), 12, STARVATION, 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 InterclassA.interclass2Bad(Interclass), 38, STARVATION, ERROR, [[Trace 1] void InterclassA.interclass2Bad(Interclass),locks `this` in class `InterclassA*`,Method call: void Interclass.interclass2Bad(),locks `this` in class `Interclass*`,[Trace 2] void Interclass.interclass1Bad(InterclassA),locks `this` in class `Interclass*`,Method call: void InterclassA.interclass1Bad(),locks `this` in class `InterclassA*`] +codetoanalyze/java/starvation/Interproc.java, void Interproc.interproc1Bad(InterprocA), 11, STARVATION, 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 InterprocA.interproc1Bad(Interproc), 39, STARVATION, ERROR, [[Trace 1] void InterprocA.interproc1Bad(Interproc),locks `this` in class `InterprocA*`,Method call: void InterprocA.interproc2Bad(Interproc),locks `d` in class `Interproc*`,[Trace 2] void Interproc.interproc1Bad(InterprocA),locks `this` in class `Interproc*`,Method call: void Interproc.interproc2Bad(InterprocA),locks `b` in class `InterprocA*`] +codetoanalyze/java/starvation/Intraproc.java, void Intraproc.intraBad(IntraprocA), 11, STARVATION, 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 IntraprocA.intraBad(Intraproc), 33, STARVATION, ERROR, [[Trace 1] void IntraprocA.intraBad(Intraproc),locks `this` in class `IntraprocA*`,locks `o` in class `Intraproc*`,[Trace 2] void Intraproc.intraBad(IntraprocA),locks `this` in class `Intraproc*`,locks `o` in class `IntraprocA*`] +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/StaticLock.java, void StaticLock.lockOtherClassOneWayBad(), 24, STARVATION, 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/VisDispFrame.java, void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad(), 19, STARVATION, ERROR, [ void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad(),calls void View.getWindowVisibleDisplayFrame(Rect) from void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad()]