infer 静态扫描

作者: 苦工 | 来源:发表于2019-05-16 12:04 被阅读62次

    随着业务迭代,完全依靠人工保证代码质量变得很不靠谱,所以静态分析工具变得很重要;通过静态语法分析能够找出在代码层面就能发现的内存泄露问题,还可以通过上下文分析出是否存在变量无用等问题。但是Xcode自带的Analyze 的功能还是有限,所以,这才诞生出了功能更全、定制化高、效率高的第三方静态检查工具,如OCLint、Infer、Clang 静态分析器等;

    综合来看,Infer 在准确性、性能效率、规则、扩展性、易用性整体度上的把握是做得最好的;


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

    infer­项目地址为https://github.com/facebook/inferinfer­

    中文网站https://infer.liaohuqiu.net

    安装infer可以参考文档https://github.com/facebook/infer/blob/master/INSTALL.md

    使用源码安装所需的时间会比较长,直接安装 binary releases 会更快些,在终端输入:brew install infer

    理论基础

    首先,infer是基于分离逻辑(Separation logic)和Bi-abduction 来实现的

    那是什么是分离逻辑呢???

    分离逻辑是霍尔逻辑的一种扩展.霍尔逻辑是广泛应用的程序验证逻辑系统,用于对命令式语言程序 进行推理验证.

    基本思想是:在代码段及其调用者之间构建一种合同似的规格说明,由一个前置条件和一个后 置条件构成.前置条件是一个断言,描述这个代码段执行前程序状态必须满足的条件;后置条件也是一个断言, 描述在代码段正确运行后程序状态所需要满足的条件,调用者可以确信在代码段执行结束后这个状态条件 为真。 在分离逻辑中,前置条件和后置条件中的程序状态主要由栈S和堆H构成,栈是变量到值的映射,而堆是有限的地址集合到值的映射.在程序验证时,可以将栈看作对寄存器内容的描述,而堆是对可寻址内存内容的描述.

    分离逻辑简而言之是推断出存储的独立小部分的一种理论,从而不用考虑每一步存储的完整性。因为考虑每一步的存储完整性对当今的大型可寻址虚拟内存处理器来说工作量太庞大

    infer 工作原理

    • 第一阶段是转化,将源码转成infer内部中间语言。c语言使用clang编译,Java语言使用javac编译,编译同时转成中间语言,输出到infer-out目录;
    • 第二阶段分析阶段,分析infer-out目录下文件每个方法,如果出现错误继续分析下一个方法,不会被中断,但会记录出错位置,然后将所有出错地方汇总输出;

    infer 使用

    • 分析单个文件 infer -- clang -c Hello.m
      实际用这个命令去分析单个文件时报错,怀疑是infer对最新的xcode兼容有问题;

    • 分析整个工程

    infer --keep-going --no-xcpretty -- xcodebuild -workspace xxx.xcworkspace -scheme xxx -configuration Debug -sdk iphonesimulator

    试了好多命令,这个可以分析完成,看分析结果bugs.txt文件

    结果分析

    在自己的工程目录下会生成infer-out 文件夹,所有的问题都收录在bugs.txt 中

    image image

    问题类型汇总

    • DEAD_STORE 未使用的变量

    • DIRECT__ATOMIC_PROPERTY_ACCESS 原子属性直接访问,在代码中使用了使用了一个atomic的成员变量,infer建议我们将atomic修改为nonatomic

    • ASSIGN___POINTER_WARNING assign修饰指针, 由于在mrc时代,没有weak指针,所以一些view的属性声明是、unsafe__unretain_的形式,在arc中,这个属性被判断为assign,需要将其修改为weak或者strong

    • 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。

    • POINTER__TO_CONST_OBJC_CLASS const错误用法

    • STRONG_DELEGATE_WARNING 将一个delegate属性设置为strong的类型

    • PREMATURE_NIL_TERMINATION_ARGUMENT 提前nil终止

    • REGISTERED_OBSERVER_BEING_DEALLOCATED 监听没有释放,创建一个对象后,监听了某些通知,但是没有在dealloc中释放该通知。项目中出现这种问题的类,基本都是单例,不会被销毁

    • PARAMETER_NOT_NULL_CHECKED 参数非空检查

    • MEMORY_LEAK 内存泄露。项目代码全面启动了ARC进行内存管理,在OC层没有扫描出内存泄露。目前扫描出的内存泄露问题都是使用了malloc或者ralloc等c语言内存申请函数,在函数提前return前没有及时free

    相关文章

      网友评论

        本文标题:infer 静态扫描

        本文链接:https://www.haomeiwen.com/subject/rlobaqtx.html