静态分析的一些总结

作者 Tsui YuenHong 日期 2017-07-26
静态分析的一些总结
  1. xxx is a garbage value

    问题描述:这个错误一般是使用一个变量前可能没有赋值引起的。

    解决方案:每次声明变量都要赋初始值(nil or 0 or 适当的值)。

  2. 1st argument .. is an uninitalized

    问题描述:传参的参数可能是没被初始化。

    解决方案:传参要保证参数是被初始化过的。

  3. nil returned from a method that is expected to return a non-null value

    问题描述:这个错误出现主要集中于 UITableViewCell 的创建或 switch x 来选择性赋值一个变量,典型例子如下。

    UITableViewCell *cell = nil;
    if(a)
    {
    cell = ...;
    }
    else if (b)
    {
    cell = ...;
    }
    return cell;
    NSString *string = nil;
    switch (x) {
    case 1:
    string = ...;
    break;
    default:
    break;
    }
    return string;

    解决方案:例子1的解决方法建议加上 else 条件来赋一个默认的 [[UITableViewCell alloc] init]。而例子2则建议 string 赋空字符串,这样 switch 的条件为空或者 default 忘记填了也保证有值返回。

  4. 由 3 延伸的问题假设 switch 的是枚举类型

    问题描述:由于枚举类型设计没有默认值,导致枚举变量赋什么值都不合适。

    解决方案:枚举设置必须含有默认值。

    typedef enum : NSUInteger {
    xxTypeDefault = 0,
    xxTypeA,
    xxTypeB,
    } xxType;
  5. xx is undefined operation

    问题描述:左移位数超过被移动对象的字节长就会提示这个 warning。

    int n = 31;
    int a = 1 << (n + 1);
    int b = 1 << 32;
    int c = 1 << 31;
    c = c << 1;
    debug print :
    1
    1606416072
    0
    release print:
    1606416072
    1606416072
    0

    出现上面结果的详细原因不作探讨,也不必探讨,因为对于不同编译器出现的结果是不同的,而且对于 undefined operation 的行为是不可预测的。

    解决方案:移位操作要对移动位数做判断,对于 int 来说就是大于等于0而且小于32。

  6. API 安全性

    问题描述:rand() or strcpy()

    解决方案:rand()->arc4random(),strcpy()->strlcpy。

    arc4random是真正是伪随机数算法,不需要随机种子。

    strlcpy保证copy后的字符串后带有’\0’,而且不会出现 buffer overflow 导致的 crash。

  7. value store to xxx is never read

    问题描述:变量被初始化后没有被使用。

    解决方案:1.删除该变量 2.使用关键字 “__unused” 修饰

  8. Potential leak of object

    问题描述:潜在内存泄漏,当需要返回值类型是 CFXXX 或者是其他需要手动管理内存的变量的时候,因为需要在当前类之外释放该变量,Xcode 会提示你释放了不属于自己管理的对象。

    解决方案:在改返回 CFXXX 的函数后加上 CF_RETURNS_RETAINED 或 将该函数命名前加上 new。

  9. 查看变量内存分配在不在栈

    lldb 下使用 register read,记录当前 sp 地址
    debug 窗口右键该变量选择 View Memory Of XXX 获取当前变量内存地址
    比对与 sp 地址的大小差距,比 sp 大在栈,比 sp 小不在栈(在堆或常量区…)