На днях Facebook выпустил новую утилиту для статического анализа кода на Java/C. Не смог пройти мимо, решил натравить его на ServerAccess.

В целом, делается это довольно тривиально: качаем, запускаем…

ahitrin@ahitrin:~/projects/ServerAccess$ ./gradlew clean
:clean

BUILD SUCCESSFUL

Total time: 2.756 secs

Если не сделать clean, то ленивый Gradle ничего не будет компилировать, и Infer не найдёт никаких ошибок. А после очистки сразу что-то нашёл!

ahitrin@ahitrin:~/projects/ServerAccess$ ~/opt/infer-linux64-v0.1.0/infer/infer/bin/infer -- ./gradlew build
Starting analysis (Infer version v0.1.0)
Analysis done

77 files analyzed


/home/ahitrin/projects/ServerAccess/src/main/java/ru/naumen/servacc/HTTPProxy.java:96: error: RESOURCE_LEAK
resource acquired by call to accept() at line 95 is not released after line 96

/home/ahitrin/projects/ServerAccess/src/main/java/ru/naumen/servacc/HTTPProxy.java:99: error: RESOURCE_LEAK
resource acquired by call to ServerSocket(...) at line 92 is not released after line 99

/home/ahitrin/projects/ServerAccess/src/main/java/ru/naumen/servacc/settings/PropertiesFile.java:56: error: RESOURCE_LEAK
resource acquired by call to FileOutputStream(...) at line 52 is not released after line 56

/home/ahitrin/projects/ServerAccess/src/main/java/ru/naumen/servacc/settings/PropertiesFile.java:60: error: RESOURCE_LEAK
resource acquired by call to FileOutputStream(...) at line 52 is not released after line 60

/home/ahitrin/projects/ServerAccess/src/test/java/ru/naumen/servacc/test/settings/FileUtils.java:34: error: RESOURCE_LEAK
resource acquired by call to FileWriter(...) at line 32 is not released after line 34

/home/ahitrin/projects/ServerAccess/src/test/java/ru/naumen/servacc/test/settings/FileUtils.java:46: error: RESOURCE_LEAK
resource acquired by call to FileReader(...) at line 40 is not released after line 46

Завёл баг, буду на досуге копаться.

Что бы ещё теперь проверить?

UDP: а вот ещё что обнаружилось…

Оказывается, что, в отличие от других средств анализа (FindBugs, PMD,..) у infer есть интересный режим работы: показ целого трейса, где происходит утечка. Это что-то новенькое!

ahitrin@ahitrin:~/projects/ServerAccess$ ~/opt/infer-linux64-v0.1.0/infer/infer/bin/inferTraceBugs --select 4 --max-level max
/home/ahitrin/projects/ServerAccess/src/test/java/ru/naumen/servacc/test/settings/FileUtils.java:34: error: RESOURCE_LEAK
resource acquired by call to FileWriter(...) at line 32 is not released after line 34

Showing all 5 steps of the trace

/home/ahitrin/projects/ServerAccess/src/test/java/ru/naumen/servacc/test/settings/FileUtils.java:29: start of procedure write(...)
27 public class FileUtils
28 {
29 > public static void write(File file, String contents) throws IOException
30 {
31 file.createNewFile();

/home/ahitrin/projects/ServerAccess/src/test/java/ru/naumen/servacc/test/settings/FileUtils.java:31:
29 public static void write(File file, String contents) throws IOException
30 {
31 > file.createNewFile();
32 PrintWriter writer = new PrintWriter(new FileWriter(file));
33 writer.print(contents);

/home/ahitrin/projects/ServerAccess/src/test/java/ru/naumen/servacc/test/settings/FileUtils.java:32:
30 {
31 file.createNewFile();
32 > PrintWriter writer = new PrintWriter(new FileWriter(file));
33 writer.print(contents);
34 writer.flush();

/home/ahitrin/projects/ServerAccess/src/test/java/ru/naumen/servacc/test/settings/FileUtils.java:33:
31 file.createNewFile();
32 PrintWriter writer = new PrintWriter(new FileWriter(file));
33 > writer.print(contents);
34 writer.flush();
35 }

/home/ahitrin/projects/ServerAccess/src/test/java/ru/naumen/servacc/test/settings/FileUtils.java:34:
32 PrintWriter writer = new PrintWriter(new FileWriter(file));
33 writer.print(contents);
34 > writer.flush();
35 }
36

Безусловно, проект ещё сырой (на большом рабочем проекте он позорно помер), но приёмчики работы у него интересные. Глядишь, что-то полезное и вырастет в итоге.



Published

18 June 2015

Tags