diff --git a/infer/src/concurrency/RacerDConfig.ml b/infer/src/concurrency/RacerDConfig.ml index 2d2e7a21d..3ba625e63 100644 --- a/infer/src/concurrency/RacerDConfig.ml +++ b/infer/src/concurrency/RacerDConfig.ml @@ -647,10 +647,10 @@ module Models = struct classes (non-channel based I/O), to methods `(Reader|InputStream).read*`. Initially, (Writer|OutputStream).(flush|close) were also matched, but this generated too many reports *) - let is_blocking_java_io = - is_call_of_class_or_superclass ["java.io.Reader"; "java.io.InputStream"] ~method_prefix:true - "read" + (* let is_blocking_java_io = + is_call_of_class_or_superclass ["java.io.Reader"; "java.io.InputStream"] ~method_prefix:true + "read" *) let actuals_are_empty_or_timeout = function | [_] -> @@ -702,8 +702,7 @@ module Models = struct let may_block = let open StarvationDomain.Event in let matchers = - [ (is_blocking_java_io, Low) - ; (is_countdownlatch_await, Medium) + [ (is_countdownlatch_await, Medium) ; (is_two_way_binder_transact, High) ; (is_getWindowVisibleDisplayFrame, Low) ; (is_future_get, High) diff --git a/infer/tests/codetoanalyze/java/starvation/Dedup.java b/infer/tests/codetoanalyze/java/starvation/Dedup.java index 513dcbbb8..910b7ddef 100644 --- a/infer/tests/codetoanalyze/java/starvation/Dedup.java +++ b/infer/tests/codetoanalyze/java/starvation/Dedup.java @@ -5,26 +5,27 @@ * LICENSE file in the root directory of this source tree. */ -import java.io.FileReader; +import java.util.concurrent.Future; +import java.util.concurrent.ExecutionException; import java.util.concurrent.CountDownLatch; import android.support.annotation.UiThread; import java.io.IOException; class Dedup { - FileReader reader; CountDownLatch latch; + Future future; // only one report should be seen @UiThread - void onUiThreadBad() throws InterruptedException, IOException { + void onUiThreadBad() throws InterruptedException, ExecutionException { callMethodWithMultipleBlocksBad(); } // three reports are expected @UiThread - void callMethodWithMultipleBlocksBad() throws InterruptedException, IOException { - reader.read(); + void callMethodWithMultipleBlocksBad() throws InterruptedException, ExecutionException { + future.get(); latch.await(); - reader.read(); + future.get(); } } diff --git a/infer/tests/codetoanalyze/java/starvation/JavaIO.java b/infer/tests/codetoanalyze/java/starvation/JavaIO.java index abaaaf531..4ba1aeb89 100644 --- a/infer/tests/codetoanalyze/java/starvation/JavaIO.java +++ b/infer/tests/codetoanalyze/java/starvation/JavaIO.java @@ -27,12 +27,12 @@ class JavaIO { } @UiThread - void fileReadBad() throws IOException { + void FN_fileReadBad() throws IOException { doFileRead(); } @UiThread - void streamReadBad() throws IOException { + void FN_streamReadBad() throws IOException { doStreamRead(); } diff --git a/infer/tests/codetoanalyze/java/starvation/issues.exp b/infer/tests/codetoanalyze/java/starvation/issues.exp index bacfea19c..520bcc5ba 100644 --- a/infer/tests/codetoanalyze/java/starvation/issues.exp +++ b/infer/tests/codetoanalyze/java/starvation/issues.exp @@ -7,10 +7,10 @@ codetoanalyze/java/starvation/Binders.java, void Binders.interBad(), 24, STARVAT codetoanalyze/java/starvation/Binders.java, void Binders.intraBad(), 30, STARVATION, no_bucket, 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(), 21, STARVATION, no_bucket, ERROR, [`void Countdwn.awaitOnMainByAnnotBad()`,calls `void CountDownLatch.await()` from `void Countdwn.awaitOnMainByAnnotBad()`] codetoanalyze/java/starvation/Countdwn.java, void Countdwn.awaitOnMainByCallBad(), 16, STARVATION, no_bucket, ERROR, [`void Countdwn.awaitOnMainByCallBad()`,calls `void CountDownLatch.await()` from `void Countdwn.awaitOnMainByCallBad()`] -codetoanalyze/java/starvation/Dedup.java, void Dedup.callMethodWithMultipleBlocksBad(), 26, STARVATION, no_bucket, ERROR, [`void Dedup.callMethodWithMultipleBlocksBad()`,calls `int InputStreamReader.read()` from `void Dedup.callMethodWithMultipleBlocksBad()`] -codetoanalyze/java/starvation/Dedup.java, void Dedup.callMethodWithMultipleBlocksBad(), 27, STARVATION, no_bucket, ERROR, [`void Dedup.callMethodWithMultipleBlocksBad()`,calls `void CountDownLatch.await()` from `void Dedup.callMethodWithMultipleBlocksBad()`] -codetoanalyze/java/starvation/Dedup.java, void Dedup.callMethodWithMultipleBlocksBad(), 28, STARVATION, no_bucket, ERROR, [`void Dedup.callMethodWithMultipleBlocksBad()`,calls `int InputStreamReader.read()` from `void Dedup.callMethodWithMultipleBlocksBad()`] -codetoanalyze/java/starvation/Dedup.java, void Dedup.onUiThreadBad(), 20, STARVATION, no_bucket, ERROR, [`void Dedup.onUiThreadBad()`,Method call: `void Dedup.callMethodWithMultipleBlocksBad()`,calls `void CountDownLatch.await()` from `void Dedup.callMethodWithMultipleBlocksBad()`] +codetoanalyze/java/starvation/Dedup.java, void Dedup.callMethodWithMultipleBlocksBad(), 27, STARVATION, no_bucket, ERROR, [`void Dedup.callMethodWithMultipleBlocksBad()`,calls `Object Future.get()` from `void Dedup.callMethodWithMultipleBlocksBad()`] +codetoanalyze/java/starvation/Dedup.java, void Dedup.callMethodWithMultipleBlocksBad(), 28, STARVATION, no_bucket, ERROR, [`void Dedup.callMethodWithMultipleBlocksBad()`,calls `void CountDownLatch.await()` from `void Dedup.callMethodWithMultipleBlocksBad()`] +codetoanalyze/java/starvation/Dedup.java, void Dedup.callMethodWithMultipleBlocksBad(), 29, STARVATION, no_bucket, ERROR, [`void Dedup.callMethodWithMultipleBlocksBad()`,calls `Object Future.get()` from `void Dedup.callMethodWithMultipleBlocksBad()`] +codetoanalyze/java/starvation/Dedup.java, void Dedup.onUiThreadBad(), 21, STARVATION, no_bucket, ERROR, [`void Dedup.onUiThreadBad()`,Method call: `void Dedup.callMethodWithMultipleBlocksBad()`,calls `Object Future.get()` from `void Dedup.callMethodWithMultipleBlocksBad()`] codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getDirectBad(), 20, STARVATION, no_bucket, ERROR, [`void FutureGet.getDirectBad()`,calls `Object Future.get()` from `void FutureGet.getDirectBad()`] codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getIndirectBad(), 25, STARVATION, no_bucket, 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, no_bucket, ERROR, [`void FutureGet.getTimeout50000001MicroSecondsBad()`,calls `Object Future.get(long,TimeUnit)` from `void FutureGet.getTimeout50000001MicroSecondsBad()`] @@ -23,8 +23,6 @@ codetoanalyze/java/starvation/InnerClass.java, void InnerClass$InnerClassA.inner codetoanalyze/java/starvation/Interclass.java, void Interclass.interclass1Bad(InterclassA), 10, DEADLOCK, no_bucket, 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), 9, DEADLOCK, no_bucket, 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), 10, DEADLOCK, no_bucket, 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(), 31, STARVATION, no_bucket, 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(), 36, STARVATION, no_bucket, 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(), 25, STARVATION, no_bucket, 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), 19, STARVATION, no_bucket, 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, no_bucket, ERROR, [`void ServiceOnUIThread.transactBad()`,calls `boolean IBinder.transact(int,Parcel,Parcel,int)` from `void ServiceOnUIThread.transactBad()`]