facebook / facebook/infer

A false negative in DEADLOCK detection

Open
#1,955 2 comments 0 reactions 0 assignees View on GitHub
false-negative java
Dominant language
OCaml
Stars
15.7k
Forks
2.1k
Avg merge
19h 36m
Merged PRs (30d)
13

Description

Hi, I found a bug in Infer's deadlock detector. Consider the following code example: methods `foo1` (line 8) and `foo2` (line 20) attempt to acquire locks `la` and `lb` in reverse order, which causes the program to hang during execution. Infer should have reported a DEADLOCK warning for this case, but no warning was actually generated. So, this is a false negative bug. It appears that Infer incorrectly assumes the concurrency bug is resolved by using `AtomicReference`.

```java
import java.util.concurrent.atomic.AtomicReference;

public class DeadlockExample {

private final AtomicReference lockA = new AtomicReference<>(new String("A"));
private final AtomicReference lockB = new AtomicReference<>(new String("B"));

private void foo1() {
Object la = lockA.get(), lb = lockB.get();
synchronized (la) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lb) {}
}
}

private void foo2() {
Object la = lockA.get(), lb = lockB.get();
synchronized (lb) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (la) {}
}
}

public static void main(String[] args) {
DeadlockExample demo = new DeadlockExample();
Thread thread1 = new Thread(() -> {
demo.oneWay();
}, "thread-1");
Thread thread2 = new Thread(() -> {
demo.anotherWay();
}, "thread-2");

thread1.start();
thread2.start();

try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
```

### Infer Log
```bash
infer run -- javac DeadlockExample.java
Capturing in javac mode...
Found 1 source file to analyze in infer-out
0/15 [..............................................................................] 0% 41.2ms
⊢ [ 0.0s][17.8M] DeadlockExample.java: void DeadlockExample.foo2()
⊢ [ 0.0s][17.8M] DeadlockExample.java: void DeadlockExample.foo1()
⊢ [ 0.0s][17.8M] idle
⊢ [ 0.0s][17.8M] idle
⊢ [ 0.0s][17.8M] idle
⊢ [ 0.0s][17.8M] idle
⊢ [ 0.0s][17.8M] DeadlockExample.java: DeadlockExample.()
⊢ [ 0.0s][17.8M] DeadlockExample.java: DeadlockExample$Lambda$_6_29.(DeadlockExample)
0/15 [..............................................................................] 0% 131ms
⊢ [ 0.1s][20.4M] DeadlockExample.java: void DeadlockExample.foo2()
⊢ [ 0.1s][20.4M] DeadlockExample.java: void DeadlockExample.foo1()
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][20.4M] DeadlockExample.java: DeadlockExample.()
⊢ [ 0.1s][17.8M] DeadlockExample.java: DeadlockExample$Lambda$_6_29.(DeadlockExample)
0/15 [..............................................................................] 0% 176ms
⊢ [ 0.1s][20.4M] DeadlockExample.java: void DeadlockExample.foo2()
⊢ [ 0.1s][20.4M] DeadlockExample.java: void DeadlockExample.foo1()
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][20.4M] DeadlockExample.java: DeadlockExample.()
⊢ [ 0.1s][17.8M] DeadlockExample.java: DeadlockExample$Lambda$_6_29.(DeadlockExample)
8/15 [#########################################.....................................] 53% 228ms
⊢ [ 0.1s][20.4M] idle
⊢ [ 0.1s][20.4M] idle
⊢ [ 0.0s][17.8M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][17.8M] DeadlockExample.java: void DeadlockExample.access_DeadlockExample$Lambda$_6_29(DeadlockExample)
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][20.4M] DeadlockExample.java: void DeadlockExample.main(String[])
⊢ [ 0.1s][17.8M] idle
13/15 [###################################################################...........] 86% 278ms
⊢ [ 0.0s][20.4M] idle
⊢ [ 0.0s][20.4M] idle
⊢ [ 0.0s][17.8M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.0s][17.8M] idle
⊢ [ 0.0s][17.8M] void DeadlockExample$Lambda$_6_13.run()
⊢ [ 0.0s][20.4M] idle
⊢ [ 0.1s][17.8M] idle
15/15 [##############################################################################] 100% 285ms
⊢ [ 0.0s][20.4M] idle
⊢ [ 0.1s][20.4M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.0s][17.8M] idle
⊢ [ 0.1s][20.4M] idle
⊢ [ 0.1s][17.8M] idle
⊢ [ 0.2s][17.8M] idle

No issues found
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.