infer是Facebook 的 Infer 是一个静态分析工具。可以分析 Objective-C, Java 或者 C 代码,报告潜在的问题。
infer项目地址为https://github.com/facebook/infer
infer中文网站https://infer.liaohuqiu.net
安装infer可以参考文档https://github.com/facebook/infer/blob/master/INSTALL.md
infer的运行原理,捕获编译命令,将文件翻译成 Infer 内部的中间语言。这种翻译和编译类似,Infer 从编译过程获取信息,并进行翻译。这就是我们调用Infer 时带上一个编译命令的原因了,比如: infer -- clang -c file.c, infer -- javac File.java。结果就是文件照常编译,同时被 Infer 翻译成中间语言,留作第二阶段处理。特别注意的就是,如果没有文件被编译,那么也没有任何文件会被分析。
infer 把中间文件存储在结果文件夹中,一般来说,这个文件夹会在运行 infer 的目录下创建,命名是 infer-out/
—————
1.把infer.sh脚本放入需要扫描的工程根目录。
2.跳转到该工程目录下,执行该sh脚本
3.扫描的问题输出在infer-out目录下
由于项目代码是在workspace文件中,可以使用xcodebuild –list 来查看workspace中的具体编译模块。
具体使用infer扫描的命令是infer -- xcodebuild -workspace "test.xcworkspace" -scheme "scheme"
在第二次使用infer扫描代码时,需要进行一次clean操作,具体的命令为xcodebuild clean -workspace "test.xcworkspace" -scheme"scheme"
扫描出的结果会在工程目录下的infer-out文件中,其中具体的代码会以csv,txt,json的格式分别存在对应的文件中。可以供我们分析
过滤:由于大家App接入了一些第三方的库,在分析代码时,可以将一些第三方库的问题进行过滤,仅显示我们自己的代码问题。
可以过滤的目录模块路径为,Pods,Weex,JSPatch,Masonry,,MBProgressHUD, PublicProjects, FXBlurView等
可以将代码扫描出的bug列表利用file属性进行过滤。过滤脚本可以参考附件。
第一次,扫描主干代码,总计扫出问题约1200个,过滤部分第三方库后,还剩下约900个。
下面简单描述一下通过infer扫描出来的问题:
1. DIRECT_ATOMIC_PROPERTY_ACCESS。在代码中使用了使用了一个atomic的成员变量,infer建议我们将atomic修改为nonatomic。由于OC中,属性会被默认设置为atomic属性,我们需要显示将属性声明为nonatomic。关于atomic与nonatomic的区别可以参见文章https://my.oschina.net/linxiaoxi1993/blog/381332
该警告占了大概800个。在代码中主动设置成员变量的nonatomic属性,即可去除警告
2. ASSIGN_POINTER_WARNING
由于在mrc时代,没有weak指针,所以一些view的属性声明是_、unsafe__unretain__的形式,在arc中,这个属性被判断为assign,需要将其修改为weak或者strong
3. NULL_DEREFERENCE
空指针的情况。根据具体代码的不同,出现空指针的情况也有所不同。
1.传参为0的情况下。例如代码中,在调用showAlertViewA()时,将tag传参为0,infer检测此处传0,判断为一个NULL空指针,所以爆出警告。这里可以理解为误报,不会出现问题。
2.通过malloc,calloc,realloc等函数申请内存,当内存不足时,有可能会在该函数中返回NULL,如果没有做NULL的判断,则警告
3.在创建NSArray或者NSDictionary时,传入的参数有可能会nil。由于NSArray与NSDictionary不接受空指针,所以在对其addObject或者setObject:forKey: 时需要进行判断一下是否为nil。
4. IVAR_NOT_NULL_CHECKED
在代码中调用block,运行代码时,没有做判空处理。即需要改动为,
if(block){block()}
5. BAD_POINTER_COMPARISON
Implicitly checking whether NSNumber pointer is nil。没有判断一个NSNumber类型的对象是不是空?此处应该是误报。
6. TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION
代码中使用了cookie的value。可以理解为误报
7. PARAMETER_NOT_NULL_CHECKED
传参时没有判断是否为null,加一次判断就可以了
8. STRONG_DELEGATE_WARNING
将一个delegate属性设置为strong的类型。
9. PREMATURE_NIL_TERMINATION_ARGUMENT
没有判断是否为空
10.REGISTERED_OBSERVER_BEING_DEALLOCATED
创建一个对象后,监听了某些通知,但是没有在dealloc中释放该通知。项目中出现这种问题的类,基本都是单例,不会被销毁。
11.MEMORY_LEAK
内存泄露。项目代码全面启动了ARC进行内存管理,在OC层没有扫描出内存泄露。目前扫描出的内存泄露问题都是使用了malloc或者ralloc等c语言内存申请函数,在函数提前return前没有及时free。