[starvation] surface caller of blocking calls in reports

Reviewed By: jeremydubreil

Differential Revision: D7727380

fbshipit-source-id: 02822ea
master
Nikos Gorogiannis 7 years ago committed by Facebook Github Bot
parent cfd9802d89
commit e5265ea85b

@ -70,8 +70,8 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
None None
in in
match instr with match instr with
| Call (_, Direct callee_pname, actuals, _, loc) -> ( | Call (_, Direct callee, actuals, _, loc) -> (
match Models.get_lock callee_pname actuals with match Models.get_lock callee actuals with
| Lock -> | Lock ->
get_path actuals |> Option.value_map ~default:astate ~f:(Domain.acquire astate loc) get_path actuals |> Option.value_map ~default:astate ~f:(Domain.acquire astate loc)
| Unlock -> | Unlock ->
@ -80,15 +80,16 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
astate astate
| NoEffect -> | NoEffect ->
if if
Models.is_countdownlatch_await callee_pname Models.is_countdownlatch_await callee
|| Models.is_two_way_binder_transact tenv actuals callee_pname || Models.is_two_way_binder_transact tenv actuals callee
|| Models.is_blocking_java_io tenv callee_pname || Models.is_blocking_java_io tenv callee
then Domain.blocking_call callee_pname loc astate then
else if is_on_main_thread callee_pname then Domain.set_on_main_thread astate let caller = Procdesc.get_proc_name pdesc in
Domain.blocking_call ~caller ~callee loc astate
else if is_on_main_thread callee then Domain.set_on_main_thread astate
else else
Summary.read_summary pdesc callee_pname Summary.read_summary pdesc callee
|> Option.value_map ~default:astate |> Option.value_map ~default:astate ~f:(Domain.integrate_summary astate callee loc) )
~f:(Domain.integrate_summary astate callee_pname loc) )
| _ -> | _ ->
astate astate
@ -212,7 +213,7 @@ let report_direct_blocks_on_main_thread proc_desc summary =
let caller_loc = Procdesc.get_loc proc_desc in let caller_loc = Procdesc.get_loc proc_desc in
let caller_pname = Procdesc.get_proc_name proc_desc in let caller_pname = Procdesc.get_proc_name proc_desc in
let error_message = let error_message =
Format.asprintf "May block while on main thread. Eventually: %a" LockEvent.pp_event Format.asprintf "UI-thread method may block; %a" LockEvent.pp_event
eventually.LockEvent.event eventually.LockEvent.event
in in
let exn = let exn =

@ -105,8 +105,8 @@ module LockEvent = struct
let make_blocks msg loc = {event= MayBlock msg; loc; trace= []} let make_blocks msg loc = {event= MayBlock msg; loc; trace= []}
let make_blocking_call pname loc = let make_blocking_call ~caller ~callee loc =
let descr = F.asprintf "Calls %a" Typ.Procname.pp pname in let descr = F.asprintf "calls %a from %a" Typ.Procname.pp callee Typ.Procname.pp caller in
make_blocks descr loc make_blocks descr loc
@ -131,9 +131,9 @@ module LockOrder = struct
let pp fmt o = let pp fmt o =
match o.first with match o.first with
| None -> | None ->
F.fprintf fmt "Eventually %a" LockEvent.pp o.eventually F.fprintf fmt "eventually %a" LockEvent.pp o.eventually
| Some lock -> | Some lock ->
F.fprintf fmt "First %a and before releasing it %a" LockEvent.pp lock LockEvent.pp F.fprintf fmt "first %a, and before releasing it, %a" LockEvent.pp lock LockEvent.pp
o.eventually o.eventually
@ -248,8 +248,8 @@ let acquire ((ls, lo), main) loc lockid =
((ls', lo'), main) ((ls', lo'), main)
let blocking_call pname loc ((ls, lo), main) = let blocking_call ~caller ~callee loc ((ls, lo), main) =
let newlock_event = LockEvent.make_blocking_call pname loc in let newlock_event = LockEvent.make_blocking_call ~caller ~callee loc in
let lo' = add_order_pairs ls newlock_event lo in let lo' = add_order_pairs ls newlock_event lo in
((ls, lo'), main) ((ls, lo'), main)

@ -62,7 +62,8 @@ val acquire : astate -> Location.t -> LockIdentity.t -> astate
val release : astate -> LockIdentity.t -> astate val release : astate -> LockIdentity.t -> astate
val blocking_call : Typ.Procname.t -> Location.t -> astate -> astate val blocking_call :
caller:Typ.Procname.t -> callee:Typ.Procname.t -> Location.t -> astate -> astate
val set_on_main_thread : astate -> astate val set_on_main_thread : astate -> astate

@ -1,13 +1,13 @@
codetoanalyze/java/starvation/Binders.java, void Binders.annotationBad(), 0, STARVATION, ERROR, [Method start: void Binders.annotationBad(),Method call: void Binders.doTransact(),Calls boolean Binder.transact(int,Parcel,Parcel,int)] codetoanalyze/java/starvation/Binders.java, void Binders.annotationBad(), 0, STARVATION, ERROR, [Method start: 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, [Method start: void Binders.interBad(),Calls boolean Binder.transact(int,Parcel,Parcel,int)] codetoanalyze/java/starvation/Binders.java, void Binders.interBad(), 0, STARVATION, ERROR, [Method start: 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, [Method start: void Binders.intraBad(),Method call: void Binders.doTransact(),Calls boolean Binder.transact(int,Parcel,Parcel,int)] codetoanalyze/java/starvation/Binders.java, void Binders.intraBad(), 0, STARVATION, ERROR, [Method start: 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, [Method start: void Countdwn.awaitOnMainByAnnotBad(),Calls void CountDownLatch.await()] codetoanalyze/java/starvation/Countdwn.java, void Countdwn.awaitOnMainByAnnotBad(), 0, STARVATION, ERROR, [Method start: void Countdwn.awaitOnMainByAnnotBad(),calls void CountDownLatch.await() from void Countdwn.awaitOnMainByAnnotBad()]
codetoanalyze/java/starvation/Countdwn.java, void Countdwn.awaitOnMainByCallBad(), 0, STARVATION, ERROR, [Method start: void Countdwn.awaitOnMainByCallBad(),Calls void CountDownLatch.await()] codetoanalyze/java/starvation/Countdwn.java, void Countdwn.awaitOnMainByCallBad(), 0, STARVATION, ERROR, [Method start: void Countdwn.awaitOnMainByCallBad(),calls void CountDownLatch.await() from void Countdwn.awaitOnMainByCallBad()]
codetoanalyze/java/starvation/InnerClass.java, void InnerClass$InnerClassA.innerOuterBad(), 0, STARVATION, ERROR, [[Trace 1] Locks this in class InnerClass$InnerClassA*,Method call: void InnerClass.bar(),Locks this in class InnerClass*,[Trace 2] 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] Locks this in class InnerClass$InnerClassA*,Method call: void InnerClass.bar(),Locks this in class InnerClass*,[Trace 2] 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] Locks this in class InnerClass*,Method call: void InnerClass$InnerClassA.baz(),Locks this in class InnerClass$InnerClassA*,[Trace 2] Method start: 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), 0, STARVATION, ERROR, [[Trace 1] Locks this in class InnerClass*,Method call: void InnerClass$InnerClassA.baz(),Locks this in class InnerClass$InnerClassA*,[Trace 2] Method start: 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 InterclassA.interclass2Bad(Interclass), 0, STARVATION, ERROR, [[Trace 1] Locks this in class InterclassA*,Method call: void Interclass.interclass2Bad(),Locks this in class Interclass*,[Trace 2] Locks this in class Interclass*,Method call: void InterclassA.interclass1Bad(),Locks this in class InterclassA*] codetoanalyze/java/starvation/Interclass.java, void InterclassA.interclass2Bad(Interclass), 0, STARVATION, ERROR, [[Trace 1] Locks this in class InterclassA*,Method call: void Interclass.interclass2Bad(),Locks this in class Interclass*,[Trace 2] 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] Locks this in class Interproc*,Method call: void Interproc.interproc2Bad(InterprocA),Locks b in class InterprocA*,[Trace 2] 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), 0, STARVATION, ERROR, [[Trace 1] Locks this in class Interproc*,Method call: void Interproc.interproc2Bad(InterprocA),Locks b in class InterprocA*,[Trace 2] Locks this in class InterprocA*,Method call: void InterprocA.interproc2Bad(Interproc),Locks d in class Interproc*]
codetoanalyze/java/starvation/Intraproc.java, void IntraprocA.intraBad(Intraproc), 0, STARVATION, ERROR, [[Trace 1] Method start: void IntraprocA.intraBad(Intraproc),Locks this in class IntraprocA*,Locks o in class Intraproc*,[Trace 2] Method start: void Intraproc.intraBad(IntraprocA),Locks this in class Intraproc*,Locks o in class IntraprocA*] codetoanalyze/java/starvation/Intraproc.java, void IntraprocA.intraBad(Intraproc), 0, STARVATION, ERROR, [[Trace 1] Method start: void IntraprocA.intraBad(Intraproc),Locks this in class IntraprocA*,Locks o in class Intraproc*,[Trace 2] Method start: 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, [Method start: void JavaIO.fileReadBad(),Method call: int JavaIO.doFileRead(),Calls int InputStreamReader.read()] codetoanalyze/java/starvation/JavaIO.java, void JavaIO.fileReadBad(), 0, STARVATION, ERROR, [Method start: 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, [Method start: void JavaIO.streamReadBad(),Method call: String JavaIO.doStreamRead(),Calls String DataInputStream.readUTF()] codetoanalyze/java/starvation/JavaIO.java, void JavaIO.streamReadBad(), 0, STARVATION, ERROR, [Method start: 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] Method start: void StaticLock.lockOtherClassOneWayBad(),Locks StaticLock$0 in class java.lang.Class*,Locks this in class StaticLock*,[Trace 2] 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(), 0, STARVATION, ERROR, [[Trace 1] Method start: void StaticLock.lockOtherClassOneWayBad(),Locks StaticLock$0 in class java.lang.Class*,Locks this in class StaticLock*,[Trace 2] Locks this in class StaticLock*,Method call: void StaticLock.staticSynced(),Locks StaticLock$0 in class java.lang.Class*]

Loading…
Cancel
Save