iOS静态分析

  • Analyzer
  • Infer
  • OCLint

Analyzer:

Clang Static Analyzer是一款静态代码扫描工具,专门用于针对C,C++和Objective-C的程序进行分析。已经被Xcode集成,可以直接使用Xcode进行静态代码扫描分析,也可以单独在命令行下使用并提供html格式的输出报吿和xml格式的结果文件方便集成到Jenkins上进行展示

Analyze主要分析以下四种问题:
1、逻辑错误:访问空指针或未初始化的变量等;
2、内存管理错误:如内存泄漏等;
3、声明错误:从未使用过的变量;
4、Api调用错误:未包含使用的库和框架。

分析车码头项目:

image.png

1.Dead store:

  • Value stored to 'stackTrace' is never read**
    如下,只是被赋值,没有被使用:
+(void)exception:(NSString *)eventCode extra:(NSDictionary *)param {
    NSString* stackTrace = [param objectForKey:MONITOR_CODE_STACK_TRACE];
    if (!stackTrace) {
        stackTrace = @"";
    }
    [[UCARMonitorNewStore sharedStore] storeException:eventCode stack:param remark:param];
}

2.Memory error:

  • nil assigned to a pointer which is expected to have non-null value
    nil 赋值给了一个期望非空值的指针
- (void)saveUserInfoModel:(id)model {
    _userInfo = nil;
    [[CMTCacheService sharedInstance] saveObject:model forKey:cmtLoginKey];
}
  • nil returned from a method that is expected to return a non-null value
    返回了 nil 值,期望返回一个非空值
- (NSArray *)getCurrentUploadModelArrWithSectionTag:(NSInteger)secTag {
    NSArray *arr;
    switch (secTag) {
        case Section2InvoiceTitle:
            arr = self.invoiceUpLoadArray;
            break;
        case Section3InputAndOutgoingVoucherTitle:
            arr = self.reciptUpLoadArray;
            break;
        case Section4OtherResources:
            arr = self.otherUpLoadArray;
            break;
    }    
    return arr;
}
  • nil passed to a callee that requires a non-null 1st parameter
    Null赋值给非空对象
        imageViewLabel.image = [UIImage imageNamed:lastImageLabel];

由于疏忽,判断语句的else里面并没有给filePath赋值,所以才会出现Null。只需进行非空判断或赋值给filePath就好了

3.Memory (Core Foundation/Objective-C)

  • Potential leak of an object stored into 'scaledImage
    存在潜在的内存泄露
- (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat)size {
    CGRect extent = CGRectIntegral(image.extent);
    CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
    
    // 1.创建bitmap;
    size_t width = CGRectGetWidth(extent) * scale;
    size_t height = CGRectGetHeight(extent) * scale;
    CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
    CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
    CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
    CGContextScaleCTM(bitmapRef, scale, scale);
    CGContextDrawImage(bitmapRef, extent, bitmapImage);
    
    // 2.保存bitmap到图片
    CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
    CGContextRelease(bitmapRef);
    CGImageRelease(bitmapImage);
    return [UIImage imageWithCGImage:scaledImage];
}

虽然是在ARC模式下,但不是什么东西都可以释放,例如上述的C-types对象,都需要手动来进行释放,所以上面的问题只需手动释放就可以了:CGImageRelease(scaledImage);
其它的如CoreFoundation对象有时候需要CFRelease,malloc/calloc等有时候需要free,还有标准IO fopen之类的需要fclose。

Infer

Facebook 的 [Infer] 是一个静态分析工具。Infer 可以分析 Objective-C, Java 或者 C 代码,报告潜在的问题。
可检测的 bug 类型:
C/OC中捕捉的bug类型

  • Resource leak
  • Memory leak
  • Null dereference
  • Premature nil termination argument

只在 OC中捕捉的bug类型

  • Retain cycle
  • Parameter not null checked
  • Ivar not null checked

工作机制

image.png

运行的两个阶段:

  1. 捕获阶段
    infer 捕获编译命令,将文件翻译成 Infer 内部的中间语言。

这种翻译和编译类似,Infer 从编译过程获取信息,并进行翻译。这就是我们调用 Infer 时带上一个编译命令的原因了,比如: infer -- clang -c file.c, infer -- javac File.java。结果就是文件照常编译,同时被 Infer 翻译成中间语言,留作第二阶段处理。特别注意的就是,如果没有文件被编译,那么也没有任何文件会被分析。

Infer 把中间文件存储在结果文件夹中,一般来说,这个文件夹会在运行 infer 的目录下创建,命名是 infer-out/。当然,你也可以通过 -o 选项来自定义文件夹名字:
infer -o /tmp/out -- javac Test.java
2.分析阶段
在分析阶段,Infer 分析 infer-out/ 下的所有文件。分析时,会单独分析每个方法和函数。

在分析一个函数的时候,如果发现错误,将会停止分析,但这不影响其他函数的继续分析。
所以你在检查问题的时候,修复输出的错误之后,需要继续运行 Infer 进行检查,知道确认所有问题都已经修复。
错误除了会显示在标准输出之外,还会输出到文件 infer-out/bug.txt 中,我们过滤这些问题,仅显示最有可能存在的。
在结果文件夹中(infer-out),同时还有一个 csv 文件 report.csv,这里包含了所有 Infer 产生的信息,包括:错误,警告和信息。

info优点
1:效率高,规模大,几分钟能扫描数千行代码;
2:支持增量及非增量分析(后边会解释)
3:分解分析,整合输出结果。(infer能将代码分解,小范围分析后再将结果整合在一起,兼顾分析的深度和速度)

安装
brew install infer
配置环境变量:
cd 你的代码文件路径//建议放到一个不常改动的位置
echo “export PATH=”$PATH:pwd/infer/infer/bin”” >> ~/.bash_profile &&source ~/.bash_profile
使用:
demo
下载后,找到 ios demo,cd命令进入ios_hello目录,然后运行以下命令进行编译
infer -- xcodebuild -target HelloWorldApp -configuration Debug -sdk iphonesimulator
参考:more...,infer 中文网

OCLint

略.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容