Facebook静态代码分析工具Infer介绍作者:暨景书,新炬网络高级技术专家。
随着IT系统的广泛应用,补丁、需求大量变更,版本快速迭代,需要频繁的进行发布,发布管理质量不高,导致故障频繁。
如何在上线采取有效措施,将一些潜在的bug扼杀在版本发布之前,优化代码,防止应用的崩溃和性能低下问题,值得我们去探索。
目前行业主要是通过静态代码分析方式,在无需运行被测代码前提下,在构建代码过程中帮助开发人员快速、有效的定位代码缺陷并及时纠正这些问题,从而极大地提高软件可靠性并节省软件开发和测试成本。
静态代码分析可以分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性,找出代码隐藏的错误和缺陷,如参数不匹配,有歧义的嵌套语句,错误的递归,非法计算,可能出现的空指针引用等。
Infer是Facebook今年刚开源一款静态分析工具。
Infer可以分析Objective-C,Java 或者C代码,重点作用于分析APP(Android/iOS)项目,报告潜在的问题。
Infer已经成为 Facebook 开发流程的一个环节,包括Facebook Android和iOS主客户端,Facebook Mes senger,Instagram在内的,以及其他影响亿万用户的手机应用,每次代码变更,都要经过Infer的检测。
先介绍infer相比其它静态分析工具有什么优点:1、是一款开源静态的代码分析工具;2、效率高,规模大,几分钟可以扫描数千行代码;3、支持增量及非增量分析;4、分解分析,整合输出结果。
Infer能将代码分解,小范围分析后再将结果整合在一起,兼顾分析的深度和速度。
Infer捕捉的bug类型:1.Java中捕捉的bug类型Resource leakNull dereference2.C/OC中捕捉的bug类型Resource leakMemory leakNull dereferencePremature nil termination argument3.只在 OC中捕捉的bug类型Retain cycleParameter not null checkedIvar not null checkedInfer官方网站主要是介绍了如何分析APP(Android/iOS)项目及单个java文件,并没有介绍针对整个JAVA项目进行分析。
大家都知道,日常中系统都是以多个java文件组成项目方式存在,本次将重点介绍如何利用Infer分析JAVA/Android项目及在部署infer时将会碰到一些问题,以避免大家在研究infer走更多的弯路。
一、Infer 处理流程Infer将Objective-C(ios)/Java/C开发程序,通过编绎器分析出相应bugs信息,目前infer支持的编译器有如下几种:编号编译器名称备注1 javac 分析单个文件2 clang 分析单个文件3 make 分析C/C++项目4 Maven 命令支持,官方无相关资料介绍,测试过无法分析java 项目,有报错现象,[ERROR] Error during capture phase, exiting此错误没有提示具体原因,待官方反馈解决参考:https:///facebook/infer/issues/1825 Ant 命令支持,官方无相关资料介绍,亲测出现Maven同样的错误,待官方反馈解决6 Gradle 主要用来分析android/JAVA项目7 Xcodebuild 分析iOS项目不管你使用哪一种编译器,infer 分析都会经过两种阶段:1.捕获阶段:Infer 捕获编译命令(上面介绍的编译器命令),将文件翻译成 Infer 内部的中间语言。
2.分析阶段:Infer将分析bugs结果输出到不同格式文件中,如csv、txt、json 方便对分析结果进行加工分析。
二、Infer安装与部署及分析1.环境要求操作系统:Ubuntu 14.04 64位,并且安装好对应的桌面,不要使用redhat操作系统(多次测试出现infer有一些包出现无法安装现象)Python版本:大于等于2.7JAVA环境:JDK 1.7,不要使用JDK 1.8(测试不支持)严格按上面要求环境下安装infer,否则只能哈哈了,惨痛的教训。
2.环境安装官方提供了预编译好的Infer工具,直接下载使用即可,测试过官方提供的最新编译好的版本0.4.0无法正常使用(无法解压)。
建议自己通过下载最新源码方式,进行手动编译后,再使用。
1)安装OCaml依赖:sudo apt-get update #更新ubt 安装源sudo apt-get upgradesudo apt-get install git openjdk-7-jdk m4 zlib1g-dev python-software-proper ties build-essential libgmp-dev libmpfr-dev libmpc-dev unzip #更新OCaml依耐包wget https:///ocaml/opam/releases/download/1.2.2/opam-1.2.2-x86_6 4-Linux -O opam #下载opamchmod +x opam./opam init --comp=4.01.0 # 然后在最后一个问题处按下“y”eval `./opam config env`./opam install sawja.1.5 atdgen.1.5.0 javalib.2.3 extlib.1.5.4 # 然后在问题处按下“y”2)下载Infer的仓库git clone https:///facebook/infer.gitcd infermake -C infer javaexport PATH=`pwd`/infer/bin:$PATH3)将infer加入环境变量中cd infer-linux64-v0.4.0 &&echo "export PATH=\"\$PATH:`pwd`/infer/infer/bin\"" \ >> ~/.bash_profile && source ~/.bash_profile4)Infer验证分析单个java 文件例子,报告输出对应java 文件存在空指针错误:报表结果输出:3.Android项目分析1)安装gradle/gradle-download/gradle-2.2.1-all.zip #对应系统版本unzip gradle-2.2.1-all.zip配置环境变量,vi ~/.bashrc添加export PATH=/opt/gradle-2.2.1/bin:$PATH保存后执行source ~/.bashrc2)安装及配置android sdk下载android-sdk_r24.3.3-linux.tgzhttps:///sdk/index.htmltar -xzvf android-sdk_r24.3.3-linux.tgzchmod -R 755 android-sdk_r24.3.3-linuxcd /opt/sdk/android-sdk-linux/tools/./android打开android sdk 图形界面,更新Android SDK Build-tools 、 Android Support R epository、Android SDK Platform-tools 23.0.1、Android 5.1.1(API 22)-SDK Platfor m 22----一定安装对应的SDK更新,否则无法正常使用。
3)安装依耐包apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0apt-get install lib32stdc++64)分析android 项目在infer 提供的例子里面(/opt/infer/infer/examples/android_hello)新建一个l ocal.properties文件并设定本地 SDK 路径sdk.dir=/opt/sdk/android-sdk-linux在infer 提供的例子里面(/opt/infer/infer/examples/android_hello)执行:infer -- ./gradlew build将分析出andorid项目bugs信息。
4.JAVA项目分析1)安装gradle同上介绍内容2)新建一个JAVA 项目(如testjava):在项目主目录下,创建以下子目录:mkdir -p src/main/java/hello└── src└── main└── java└── hello在src/main/java/hello目录中,你可以创建任何Java类。
为简单起见并且为了与指南的其余部分保持一致,我们建议创建两个雷HelloWorld.java和Greeter.java src/main/java/hello/HelloWorld.java的源代码:package hello;public class HelloWorld {public static void main(String[] args) {Greeter greeter = new Greeter();System.out.println(greeter.sayHello());}}src/main/java/hello/Greeter.java的源代码:package hello;public class Greeter {public String sayHello() {return "Hello world!";}}3)在java 项目下,新建gradle 编译器配置文件build.gradleapply plugin: 'java'4)分析java 项目gradle clean #清除当前项目编译任务infer -- gradle build当出现如下信息时表示处理成功:Starting analysis (Infer version git-401109b4eb9d54ef8831ee953a3436ec3e2bb7 2e)Analysis finished in 0.047985ssrc/main/java/hello/Greeter.java:6: error: NULL_DEREFERENCEobject s last assigned on line 5 could be null and is dereferenced at lin e 6src/main/java/hello/HelloWorld.java:12: error: NULL_DEREFERENCEobject s last assigned on line 11 could be null and is dereferenced at li ne 12从上面可以看出利infer 可以经松分析出代码项目bugs信息,为代码优化指明了方向。