[starvation] catch calls to Thread.sleep

Summary: Treat calls to Thread.sleep as blocking, even when the timeouts are less than the ANR limit.

Reviewed By: da319

Differential Revision: D9027950

fbshipit-source-id: 001409896
master
Nikos Gorogiannis 6 years ago committed by Facebook Github Bot
parent 332bd365e8
commit 3870ebb747

@ -735,6 +735,9 @@ module Models = struct
|> Staged.unstage |> Staged.unstage
(* consider any call to sleep as bad, even with timeouts lower than the anr limit *)
let is_thread_sleep = is_call_of_class ["java.lang.Thread"] "sleep" |> Staged.unstage
(* at most one function is allowed to be true, sort from High to Low *) (* at most one function is allowed to be true, sort from High to Low *)
let may_block = let may_block =
let open StarvationDomain.Event in let open StarvationDomain.Event in
@ -742,6 +745,7 @@ module Models = struct
[ (is_accountManager_setUserData, High) [ (is_accountManager_setUserData, High)
; (is_two_way_binder_transact, High) ; (is_two_way_binder_transact, High)
; (is_countdownlatch_await, High) ; (is_countdownlatch_await, High)
; (is_thread_sleep, High)
; (is_object_wait, High) ; (is_object_wait, High)
; (is_getWindowVisibleDisplayFrame, Medium) ; (is_getWindowVisibleDisplayFrame, Medium)
; (is_asyncTask_get, Low) ; (is_asyncTask_get, Low)

@ -0,0 +1,34 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import android.support.annotation.UiThread;
import java.lang.Thread;
class ThreadSleep {
void sleepOnAnyThreadOk() throws InterruptedException {
Thread.sleep(60);
}
@UiThread
void sleepOnUIThreadBad() throws InterruptedException {
Thread.sleep(60);
}
Object lock;
@UiThread
void indirectSleepOnUIThreadBad() {
synchronized(lock) {}
}
void lockAndSleepOnNonUIThread() throws InterruptedException {
synchronized(lock) {
sleepOnAnyThreadOk();
}
}
}

@ -38,5 +38,7 @@ codetoanalyze/java/starvation/ServiceOnUIThread.java, IBinder ServiceOnUIThread.
codetoanalyze/java/starvation/ServiceOnUIThread.java, void ServiceOnUIThread.transactBad(), 25, STARVATION, no_bucket, 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, no_bucket, ERROR, [`void ServiceOnUIThread.transactBad()`,calls `boolean IBinder.transact(int,Parcel,Parcel,int)` from `void ServiceOnUIThread.transactBad()`]
codetoanalyze/java/starvation/StaticLock.java, void StaticLock.lockOtherClassOneWayBad(), 23, DEADLOCK, no_bucket, 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(), 23, DEADLOCK, no_bucket, 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/SuppLint.java, void SuppLint.onUiThreadBad(), 26, STARVATION, no_bucket, ERROR, [`void SuppLint.onUiThreadBad()`,calls `Object Future.get()` from `void SuppLint.onUiThreadBad()`] codetoanalyze/java/starvation/SuppLint.java, void SuppLint.onUiThreadBad(), 26, STARVATION, no_bucket, ERROR, [`void SuppLint.onUiThreadBad()`,calls `Object Future.get()` from `void SuppLint.onUiThreadBad()`]
codetoanalyze/java/starvation/ThreadSleep.java, void ThreadSleep.indirectSleepOnUIThreadBad(), 25, STARVATION, no_bucket, ERROR, [[Trace 1] `void ThreadSleep.indirectSleepOnUIThreadBad()`,locks `this.ThreadSleep.lock` in class `ThreadSleep*`,[Trace 2] `void ThreadSleep.lockAndSleepOnNonUIThread()`,locks `this.ThreadSleep.lock` in class `ThreadSleep*`,Method call: `void ThreadSleep.sleepOnAnyThreadOk()`,calls `void Thread.sleep(long)` from `void ThreadSleep.sleepOnAnyThreadOk()`]
codetoanalyze/java/starvation/ThreadSleep.java, void ThreadSleep.sleepOnUIThreadBad(), 18, STARVATION, no_bucket, ERROR, [`void ThreadSleep.sleepOnUIThreadBad()`,calls `void Thread.sleep(long)` from `void ThreadSleep.sleepOnUIThreadBad()`]
codetoanalyze/java/starvation/UIDeadlock.java, void UIDeadlock.onUIThreadBad(), 26, DEADLOCK, no_bucket, 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(), 26, DEADLOCK, no_bucket, 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(), 18, STARVATION, no_bucket, ERROR, [`void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad()`,calls `void View.getWindowVisibleDisplayFrame(Rect)` from `void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad()`] codetoanalyze/java/starvation/VisDispFrame.java, void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad(), 18, STARVATION, no_bucket, ERROR, [`void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad()`,calls `void View.getWindowVisibleDisplayFrame(Rect)` from `void VisDispFrame.callsGetVisibleDisplayFrameOnUiThreadBad()`]

Loading…
Cancel
Save