[starvation] enable starvation checker

Summary:
Make the starvation checker enabled by default.
Add a deadlock issue type, distinct to starvation, which will be kept for UI thread starvation.
Add checks so that checker will do nothing on non-Java code.

Reviewed By: mbouaziz, ddino

Differential Revision: D7908381

fbshipit-source-id: 889f373
master
Nikos Gorogiannis 7 years ago committed by Facebook Github Bot
parent 28b696881c
commit a7bd92de2f

@ -141,6 +141,8 @@ let dangling_pointer_dereference = from_string ~enabled:false "DANGLING_POINTER_
let dead_store = from_string "DEAD_STORE"
let deadlock = from_string "DEADLOCK"
let deallocate_stack_variable = from_string "DEALLOCATE_STACK_VARIABLE"
let deallocate_static_memory = from_string "DEALLOCATE_STATIC_MEMORY"

@ -96,6 +96,8 @@ val dangling_pointer_dereference : t
val dead_store : t
val deadlock : t
val deallocate_stack_variable : t
val deallocate_static_memory : t

@ -102,7 +102,15 @@ let get_class_of_pname = function
None
let die_if_not_java proc_desc =
let is_java =
Procdesc.get_proc_name proc_desc |> Typ.Procname.get_language |> Language.(equal Java)
in
if not is_java then L.(die InternalError "Not supposed to run on non-Java code yet.")
let analyze_procedure {Callbacks.proc_desc; tenv; summary} =
die_if_not_java proc_desc ;
let pname = Procdesc.get_proc_name proc_desc in
let formals = FormalMap.make proc_desc in
let proc_data = ProcData.make proc_desc tenv formals in
@ -183,7 +191,7 @@ let report_deadlocks get_proc_desc tenv current_pdesc (summary, current_main) =
endpoint_pname LockOrder.pp elem
in
let exn =
Exceptions.Checkers (IssueType.starvation, Localise.verbatim_desc error_message)
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
@ -209,10 +217,11 @@ let report_deadlocks get_proc_desc tenv current_pdesc (summary, current_main) =
(* for each summary related to the endpoint, analyse and report on its pairs *)
List.iter endpoint_summaries ~f:(fun (endpoint_pdesc, (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
)
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 )
in
LockOrderDomain.iter report_on_current_elem summary
@ -244,7 +253,7 @@ 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
Format.asprintf "UI thread method may block; %a" LockEvent.pp_event
eventually.LockEvent.event
in
let exn =
@ -278,6 +287,7 @@ let report_blocks_on_main_thread get_proc_desc tenv current_pdesc summary =
let reporting {Callbacks.procedures; get_proc_desc; exe_env} =
let report_procedure (tenv, proc_desc) =
die_if_not_java 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 ;

@ -9,19 +9,19 @@ codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getDirectBad(), 19,
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.<init>(InnerClass,Object), 49, STARVATION, 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, 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.<init>(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/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.outerInnerBad(InnerClass$InnerClassA), 19, DEADLOCK, 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.<init>(InnerClass,Object),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, DEADLOCK, 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/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 InterclassA.interclass2Bad(Interclass), 38, DEADLOCK, 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, 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 InterprocA.interproc1Bad(Interproc), 39, DEADLOCK, 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, 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 IntraprocA.intraBad(Intraproc), 33, DEADLOCK, 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/UIDeadlock.java, void UIDeadlock.notOnUIThreadBad(), 32, STARVATION, ERROR, [[Trace 1] void UIDeadlock.notOnUIThreadBad(),locks `this.UIDeadlock.lockB` in class `UIDeadlock*`,locks `this` in class `UIDeadlock*`,[Trace 2] void UIDeadlock.onUIThreadBad(),locks `this` in class `UIDeadlock*`,locks `this.UIDeadlock.lockB` in class `UIDeadlock*`]
codetoanalyze/java/starvation/UIDeadlock.java, void UIDeadlock.onUIThreadBad(), 28, STARVATION, 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/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.notOnUIThreadBad(), 32, DEADLOCK, ERROR, [[Trace 1] void UIDeadlock.notOnUIThreadBad(),locks `this.UIDeadlock.lockB` in class `UIDeadlock*`,locks `this` in class `UIDeadlock*`,[Trace 2] void UIDeadlock.onUIThreadBad(),locks `this` in class `UIDeadlock*`,locks `this.UIDeadlock.lockB` 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()]

Loading…
Cancel
Save