什么是 Infer?
Facebook 的 Infer 是一个静态分析工具。Infer 可以分析 Objective-C, Java 或者 C 代码,报告潜在的问题。

任何人都可以使用 Infer 检测应用,这可以将那些严重的 bug 扼杀在发布之前,同时防止应用崩溃和性能低下。
这是infer的官网,更加详细的资料可以在上面查看。
因为刚开始接触infer
,只是了解了最基本的一些使用,后续有一些新的了解都会在该篇文章上做记录。
安装infer
最简单的安装方法就是使用Homebrew
,可能需要翻墙。
brew install infer
当你运行再linux或者不想使用homebrew安装的时候,你可以使用最新的release版本。
VERSION=0.XX.Y; \
curl -sSL "https://github.com/facebook/infer/releases/download/v$VERSION/infer-linux64-v$VERSION.tar.xz" \
| sudo tar -C /opt -xJ && \
ln -s "/opt/infer-linux64-v$VERSION/bin/infer" /usr/local/bin/infer
使用infer
官网中是以hello world
为例来讲解。这边就偷懒直接引用官方的例子
Hello world Objective-C
以下是一个简单的 Objective-C 例子:
// Hello.m
#import <Foundation/Foundation.h>
@interface Hello: NSObject
@property NSString* s;
@end
@implementation Hello
NSString* m() {
Hello* hello = nil;
return hello->_s;
}
@end
在 Hello.m
同级目录,运行:
infer run -- clang -c Hello.m
以下是错误报告输出:
Hello.m:10 NULL_DEREFERENCE
pointer hello last assigned on line 9 could be null and is dereferenced at line 10, column 12
编辑,如下修正:
NSString* m() {
Hello* hello = nil;
return hello.s;
}
再次运行,No issues found
, 没有报错。
Hello world iOS
iOS 的示例代码在这里 infer/examples/ios_hello
,使用 Infer 检测:
infer run -- xcodebuild -target HelloWorldApp -configuration Debug -sdk iphonesimulator
将会有以下问题输出:
AppDelegate.m:20: error: MEMORY_LEAK
memory dynamically allocated to shadowPath by call to CGPathCreateWithRect() at line 20, column 28 is not reachable after line 20, column 5
AppDelegate.m:25: error: RESOURCE_LEAK
resource acquired to fp by call to fopen() at line 25, column 8 is not released after line 25, column 5
AppDelegate.m:29: warning: PARAMETER_NOT_NULL_CHECKED
Parameter callback is not checked for null, there could be a null pointer dereference: pointer callback could be null and is dereferenced at line 29, column 5
AppDelegate.m:34: error: NULL_DEREFERENCE
pointer str last assigned on line 33 could be null and is dereferenced at line 34, column 12
AppDelegate.m:39: error: PREMATURE_NIL_TERMINATION_ARGUMENT
pointer str last assigned on line 38 could be nil which results in a call to arrayWithObjects: with 1 arguments instead of 3 (nil indicates that the last argument of this variadic method has been reached) at line 39, column 12
Hello.m:20: error: NULL_DEREFERENCE
pointer hello last assigned on line 19 could be null and is dereferenced at line 20, column 12
Hello.m:25: warning: IVAR_NOT_NULL_CHECKED
Instance variable hello -> _hello is not checked for null, there could be a null pointer dereference: pointer ret_hello last assigned on line 24 could be null and is dereferenced at line 25, column 12
Hello.m:30: warning: PARAMETER_NOT_NULL_CHECKED
Parameter hello is not checked for null, there could be a null pointer dereference: pointer ret_hello last assigned on line 29 could be null and is dereferenced at line 30, column 12
和gradle, 运行同样的命令第二次,可能得不到分析结果,由于没有重新编译,需要使用 ----reactive
(或 -r
) 使得增量编译有结果输出。
infer run --reactive -- xcodebuild -target HelloWorldApp -configuration Debug -sdk iphonesimulator
或者在编译前清理:
xcodebuild -target HelloWorldApp -configuration Debug -sdk iphonesimulator clean
现在大多项目都是以workspace的形式,那么workspace怎么使用infer来检测呢?
infer run -- xcodebuild -workspace <your name>.xcworkspace -scheme <your scheme> -configuration Debug -sdk iphonesimulator
运行成功之后,会在根目录下生成infer-out
文件目录,里面包含分析日志。

其中bugs.txt
中就是infer分析之后检测出的问题所在,我们就可以通过该信息修复潜在的问题。
下面是infer跑本地demo输出的信息。
Found 4 issues
directory/ViewController.m:21: error: RETAIN_CYCLE
Retain cycle at line 21, column 10 involving the following objects:
(1) a block that captures `self`
(2) object of type `ViewController*` --> `_testBlock`, last assigned on line 21.
19.
20. - (void)test {
21. > self.testBlock = ^{
22. NSLog(@"%@", self.age);
23. };
...
Summary of the reports
BAD_POINTER_COMPARISON: 2
RETAIN_CYCLE: 1
ASSIGN_POINTER_WARNING: 1
网友评论