iOS靜態(tài)分析:Infer的使用

一瓦宜、Infer簡介

Facebook 的 Infer 是一個靜態(tài)分析工具临庇。Infer 可以分析 Objective-C假夺, Java 或者 C 代碼已卷,報告潛在的問題侧蘸。任何人都可以使用 Infer 檢測應(yīng)用讳癌,這可以將那些嚴(yán)重的 bug 扼殺在發(fā)布之前晌坤,同時防止應(yīng)用崩潰和性能低下骤菠。Infer 可檢查 Android 和 Java 代碼中的 NullPointException 和 資源泄露娩怎。除了以上胰柑,Infer 還可發(fā)現(xiàn) iOS 和 C 代碼中的內(nèi)存泄露。

Infer 已經(jīng)成為 Facebook 開發(fā)流程的一個環(huán)節(jié)崩瓤,包括 Facebook Android 和 iOS 主客戶端,F(xiàn)acebook Messenger颖系, Instagram 在內(nèi)的嘁扼,以及其他影響億萬用戶的手機(jī)應(yīng)用黔攒,每次代碼變更趁啸,都要經(jīng)過 Infer 的檢測。

Infer簡介.png

二督惰、Infer安裝

1不傅、Homebrew 安裝

brew install infer

如果安裝太久,或者安裝失敗赏胚,也可以使用下面的安裝包的方式進(jìn)行安裝

2访娶、安裝包安裝

1)GitHub下載安裝包:https://github.com/facebook/infer/releases 選擇對應(yīng)的版本,進(jìn)行下載觉阅。

2)下載后進(jìn)行解壓崖疤,解壓后會有一個 infer-osx-v1.0.0 目錄戳晌,v1.0.0是對應(yīng)的版本號豪嚎。主執(zhí)行目錄是infer-osx-v1.0.0/lib/infer/infer/bin/

3)設(shè)置PATH變量糯耍。建議把 Infer 的執(zhí)行目錄加入到環(huán)境變量中扭粱,這樣使用起來會簡便一些博其。當(dāng)然儡率,你也可以用絕對路徑眉孩。本文檔后續(xù)默認(rèn)執(zhí)行路徑已加入到環(huán)境變量中死遭。

open ~/.bash_profile
export PATH="${PATH}:/Users/zjh48/Documents/infer-osx-v1.0.0/lib/infer/infer/bin"
source ~/.bash_profile

注意 export PATH="${PATH}:/Users/zjh48/Documents/infer-osx-v1.0.0/lib/infer/infer/bin" 這個需要寫成自己的路徑

4)執(zhí)行 infer --version钠署,如果輸出對應(yīng)的版本狸棍,則說明安裝成功

三傍菇、Infer的使用

1咐低、Infer基本用法

我們可以新建一個測試工程InferTest损痰,并在 ViewController.m 中辽社,寫上一段代碼:

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *str = @"1";
}

@end

首先用cd命令進(jìn)入InferTest目錄,然后運(yùn)行以下命令進(jìn)行編譯:

infer -- xcodebuild -target InferTest -configuration Debug -sdk iphonesimulator

執(zhí)行結(jié)束后,終端上面會展示錯誤信息,在項目所在目錄下也會多出buildinfer-out文件夾,其中report.txt中的信息和終端上的信息一樣

Infer編譯分析出問題.png

可以看出阅懦,我們的 ViewController.m 代碼里有1個問題怕午,將代碼修改如下:

NSString *str = @"1";
NSLog(@"str = %@",str);

先手動刪除build文件夾(清除編譯信息), 再次執(zhí)行上述命令郁惜,重新編譯:

infer -- xcodebuild -target InferTest -configuration Debug -sdk iphonesimulator

執(zhí)行結(jié)果:

Infer編譯分析沒有問題.png

恭喜??????,問題已經(jīng)消除甲锡,以上就是infer的基本用法缤沦。

2、可能出現(xiàn)的問題

1)出現(xiàn)xcode-select: error

xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

這種情況是這種情況是xcodebuild的路徑不正確姆泻。將路徑切換到Xcode的目錄下,如下:

sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/

2)在兩次執(zhí)行編譯命令的過程中妓肢,發(fā)現(xiàn)在沒有對代碼做任何更改的時候(bug還在)色徘,報出BUILD SUCCEEDED的提示:

Infer編譯沒變化.png

根據(jù)提示可以看到,此次build并沒有分析任何文件操禀。原因涉及到增量分析,默認(rèn)編譯的是有改變的代碼横腿,下一小節(jié)會詳細(xì)介紹颓屑。

3、增量模式和非增量模式

第一次運(yùn)行的時候耿焊,兩種模式是一樣的揪惦,都會對工程的所有文件進(jìn)行編譯檢查,產(chǎn)生檢查結(jié)果:
增量模式:當(dāng)已經(jīng)產(chǎn)生分析結(jié)果后(build和infer-out文件夾)罗侯,再執(zhí)行編譯命令器腋,即為增量模式。如有代碼沒有改動钩杰,則此次不會有編譯結(jié)果產(chǎn)生纫塌,如果代碼有新的改動,此次只產(chǎn)生新的編譯結(jié)果讲弄。這種以增量為基準(zhǔn)的原則叫做增量模式措左。
非增量模式:在刪除了倆個文件夾的情況下,運(yùn)行文件避除,會輸出所有的編譯信息怎披,即此時處于非增量模式。

增量模式轉(zhuǎn)化為非增量模式:

第1種瓶摆、直接刪除文件夾(build和infer-out文件夾)

第2種凉逛、先使用xcodebuild clean 清除一下對應(yīng)的 target 工程,之后再重新編譯分析

xcodebuild -target InferTest -configuration Debug -sdk iphonesimulator clean

4群井、分析帶cocoapods的項目

1)執(zhí)行命令

先識別 /***.xcworkspace状飞,再識別 scheme

infer -- xcodebuild -workspace InferTest.xcworkspace -scheme InferTest -configuration Debug -sdk iphonesimulator

這種方法會分享所有的代碼,而當(dāng)我們在項目中使用了很多第三方的時候,其實(shí)我們只想讓Infer分析我們的代碼昔瞧,而不想分析第三方的代碼指蚁,不然分析報告中會有很多第三方的issue,看著混亂自晰,這時我們可以用命令行過濾掉關(guān)于不想分析的文件凝化。比如用到cocoapods的項目,我們想過濾掉Pods引入的第三方庫酬荞。

2)過濾三方庫

方法一

在命令行里添加過濾條件:INFER_ARGS="--skip-clang-analysis-in-path^[\"Pods\"]"

INFER_ARGS="--skip-clang-analysis-in-path^[\"Pods\"]" infer -- xcodebuild -workspace InferTest.xcworkspace -scheme InferTest -configuration Debug -sdk iphonesimulator

in-path 后面跟的是一個忽略文件或者文件夾的路徑數(shù)組搓劫。

方法二

在工程目錄下新建 .inferconfig 文件, 內(nèi)容如圖, 可以過濾掉Pods文件夾下的第三方庫, skip-analysis-in-path是一個數(shù)組, 想要過濾其他文件, 只需要增加路徑即可混巧。

inferconfig配置文件.png

1枪向、in-path 后面跟的是一個忽略文件或者文件夾的路徑數(shù)組。
2咧党、["Pods"] 代表過濾所有的 Pods 文件
3秘蛔、["Pods/AFNetworking","Pods/Masonry"] 代表過濾 AFNetworking、Masonry 三方庫
4傍衡、也可以寫個腳本對解析出來的文件進(jìn)行二次拆分深员,按組件模塊、錯誤和警告劃分

四蛙埂、Infer工作流程

不管是分析哪種語言倦畅,Infer 運(yùn)行時,分為兩個主要階段:捕獲階段绣的、分析階段

1叠赐、捕獲階段

Infer 捕獲編譯命令,將文件翻譯成 Infer 內(nèi)部的中間語言屡江。

這種翻譯和編譯類似芭概,Infer 從編譯過程獲取信息,并進(jìn)行翻譯盼理。這就是我們調(diào)用 Infer 時帶上一個編譯命令的原因了谈山,比如: infer -- clang -c file.c, infer -- javac File.java。結(jié)果就是文件照常編譯宏怔,同時被 Infer 翻譯成中間語言奏路,留作第二階段處理。特別注意的就是臊诊,如果沒有文件被編譯鸽粉,那么也沒有任何文件會被分析。

Infer 把中間文件存儲在結(jié)果文件夾中抓艳,一般來說焰宣,這個文件夾會在運(yùn)行 infer 的目錄下創(chuàng)建嗡呼,命名是 infer-out/恋日。當(dāng)然吃挑,你也可以通過 -o 選項來自定義文件夾名字

2票顾、分析階段

在分析階段,Infer 分析 infer-out/ 下的所有文件。分析時,會單獨(dú)分析每個方法和函數(shù)对供。

在分析一個函數(shù)的時候,如果發(fā)現(xiàn)錯誤氛濒,將會停止分析产场,但這不影響其他函數(shù)的繼續(xù)分析。所以你在檢查問題的時候舞竿,修復(fù)輸出的錯誤之后京景,需要繼續(xù)運(yùn)行 Infer 進(jìn)行檢查,知道確認(rèn)所有問題都已經(jīng)修復(fù)骗奖。

錯誤除了會顯示在標(biāo)準(zhǔn)輸出之外确徙,還會輸出到文件 infer-out/bug.txt 中,我們過濾這些問題重归,僅顯示最有可能存在的米愿。在結(jié)果文件夾中(infer-out),同時還有一個 csv 文件 report.csv鼻吮,這里包含了所有 Infer 產(chǎn)生的信息,包括:錯誤较鼓,警告和信息椎木。

Infer 的工作流程圖.png

五、常見掃描錯誤

1博烂、DIRECT_ATOMIC_PROPERTY_ACCESS香椎。

在代碼中使用了使用了一個atomic的成員變量,infer建議我們將atomic修改為nonatomic禽篱。由于OC中畜伐,屬性會被默認(rèn)設(shè)置為atomic屬性,我們需要顯示將屬性聲明為nonatomic躺率。關(guān)于atomic與nonatomic的區(qū)別可以參見文章https://my.oschina.net/linxiaoxi1993/blog/381332
該警告占了大概800個玛界。在代碼中主動設(shè)置成員變量的nonatomic屬性,即可去除警告

2悼吱、ASSIGN_POINTER_WARNING

由于在mrc時代慎框,沒有weak指針,所以一些view的屬性聲明是后添、unsafe__unretain_的形式笨枯,在arc中,這個屬性被判斷為assign,需要將其修改為weak或者strong

3馅精、NULL_DEREFERENCE

空指針的情況严嗜。根據(jù)具體代碼的不同,出現(xiàn)空指針的情況也有所不同洲敢。
1)傳參為0的情況下漫玄。例如代碼中,在調(diào)用showAlertViewA()時沦疾,將tag傳參為0,infer檢測此處傳0称近,判斷為一個NULL空指針,所以爆出警告哮塞。這里可以理解為誤報刨秆,不會出現(xiàn)問題。
2)通過malloc,calloc,realloc等函數(shù)申請內(nèi)存忆畅,當(dāng)內(nèi)存不足時衡未,有可能會在該函數(shù)中返回NULL,如果沒有做NULL的判斷家凯,則警告
3)在創(chuàng)建NSArray或者NSDictionary時缓醋,傳入的參數(shù)有可能會nil。由于NSArray與NSDictionary不接受空指針绊诲,所以在對其addObject或者setObject:forKey: 時需要進(jìn)行判斷一下是否為nil送粱。

4、IVAR_NOT_NULL_CHECKED

在代碼中調(diào)用block掂之,運(yùn)行代碼時抗俄,沒有做判空處理。即需要改動為世舰,
if(block){block()}

5动雹、BAD_POINTER_COMPARISON

Implicitly checking whether NSNumber pointer is nil。沒有判斷一個NSNumber類型的對象是不是空跟压?此處應(yīng)該是誤報胰蝠。

6、TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION

代碼中使用了cookie的value震蒋∪兹可以理解為誤報

7、PARAMETER_NOT_NULL_CHECKED

傳參時沒有判斷是否為null喷好,加一次判斷就可以了

8翔横、STRONG_DELEGATE_WARNING

將一個delegate屬性設(shè)置為strong的類型。

9梗搅、PREMATURE_NIL_TERMINATION_ARGUMENT

沒有判斷是否為空

10禾唁、REGISTERED_OBSERVER_BEING_DEALLOCATED

創(chuàng)建一個對象后效览,監(jiān)聽了某些通知,但是沒有在dealloc中釋放該通知荡短。項目中出現(xiàn)這種問題的類丐枉,基本都是單例,不會被銷毀掘托。

11瘦锹、MEMORY_LEAK

內(nèi)存泄露。項目代碼全面啟動了ARC進(jìn)行內(nèi)存管理闪盔,在OC層沒有掃描出內(nèi)存泄露弯院。目前掃描出的內(nèi)存泄露問題都是使用了malloc或者ralloc等c語言內(nèi)存申請函數(shù),在函數(shù)提前return前沒有及時free泪掀。



參考鏈接:
infer官網(wǎng):https://fbinfer.com/docs/getting-started.html
infer中文網(wǎng)站:https://infer.liaohuqiu.net
iOS infer靜態(tài)分析工具使用:http://www.reibang.com/p/fd1923cc87eb
iOS-App接入infer靜態(tài)分析掃描工具:http://www.reibang.com/p/52f61498e2b2
iOS開發(fā)之使用 infer靜態(tài)代碼掃描工具:https://www.cnblogs.com/ZachRobin/p/11280499.html
xcode-select --install 解決方案:https://blog.csdn.net/lucky9322/article/details/79036877

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末听绳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子异赫,更是在濱河造成了極大的恐慌椅挣,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塔拳,死亡現(xiàn)場離奇詭異鼠证,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)靠抑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進(jìn)店門量九,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人颂碧,你說我怎么就攤上這事娩鹉。” “怎么了稚伍?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長戚宦。 經(jīng)常有香客問我个曙,道長,這世上最難降的妖魔是什么受楼? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任垦搬,我火速辦了婚禮,結(jié)果婚禮上艳汽,老公的妹妹穿的比我還像新娘猴贰。我一直安慰自己,他們只是感情好河狐,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布米绕。 她就那樣靜靜地躺著瑟捣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪栅干。 梳的紋絲不亂的頭發(fā)上迈套,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天,我揣著相機(jī)與錄音碱鳞,去河邊找鬼桑李。 笑死,一個胖子當(dāng)著我的面吹牛窿给,可吹牛的內(nèi)容都是我干的贵白。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼崩泡,長吁一口氣:“原來是場噩夢啊……” “哼禁荒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起允华,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤圈浇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后靴寂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體磷蜀,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年百炬,在試婚紗的時候發(fā)現(xiàn)自己被綠了褐隆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡剖踊,死狀恐怖庶弃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情德澈,我是刑警寧澤歇攻,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站梆造,受9級特大地震影響缴守,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜镇辉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一屡穗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧忽肛,春花似錦村砂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汛骂。三九已至,卻和暖如春色迂,著一層夾襖步出監(jiān)牢的瞬間香缺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工歇僧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留图张,地道東北人。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓诈悍,卻偏偏與公主長得像祸轮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子侥钳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評論 2 359

推薦閱讀更多精彩內(nèi)容