使用facebook infer尋找項目潛在BUG

什麼是Infer?

Facebook的infer是一個靜態分析工具,如果你給定infer Objective-C,Java或C代碼,它將分析潛在的bug列表。

任何人都可以使用infer攔截嚴重的安全漏洞,在應用上線之前有助於防止崩潰或性能不佳。

so

什麼是靜態分析呢?要知道我們調試bug的時候,都是運行逐行檢查代碼,而infer能在不運行程序的情況下進行代碼分析,wow~有點AI的趕腳。

Infer能將代碼分解,小範圍分析後再將結果整合在一起,兼顧分析的深度和速度。


產品特點

Android和Java

報告空指針異常和資源泄漏。

iOS(本文以在Mac及IOS案例爲主,android and java留坑慢填

除以上之外,報告iOS和C代碼的內存泄漏問題。

誰在使用infer?

它是用來作爲Facebook發展過程中移動應用程序的一部分 - 其中包括主要的Facebook應用程序的Andr​​oid和iOS,Facebook的messenger,Instagram,並且所使用的超過十億用戶的其他應用程序。

so

沒事兒弄來玩一玩還是很不錯的哈~(老闆:(╯°□°)╯︵ ┻━┻ 給勞資寫代碼去!不然扣你KPI  )


---------LET'S GO-----------------------------------

ok,接下來我們快速的做一個DEMO來初步運用infer這個強大的工具吧,嗯,因爲要去買菜了所以有點趕哈(老闆:(╯°□°)╯︵ ┻━┻ 上班你去買菜!!!!丟你個嗨!!!)

首先發布幾個官方地址:
facebook infer官網(請自備梯子)
github地址(對下面的DEMO來講沒卵用,所以暫時不用download這個……)

--買菜先~-----------
------INSTALL-------
安裝需要Python >=2.7版本,Mac自帶了,good!

一、下載

緊接着,下載
或者從這裏獲取最新版本

二、解壓
然後打開終端terminal,使用cd命令進入你下載的文件目錄(你最好存在一個單獨的目錄中~)
如果你是Mac的話,運行以下命令解壓(注意你下載的文件名、版本號,別隻copy啊~)
tar xf infer-osx-v0.1.0.tar.xz
如果你是Linux的話,運行以下命令解壓(注意你下載的文件名、版本號,別隻copy啊~)
tar xf infer-linux64-v0.1.0.tar.xz
注意你下載的文件名、版本號,別隻copy啊~重要的話要重複三遍…… 

三、將包路徑添加到環境變量當中

tips:因爲要把路徑添加到環境變量中,這裏建議先把目錄放到一個不常使用的地方,避免以後不注意(or不記得這是什麼鬼)刪掉了,那麼這玩意兒也沒法使用了;類似於android sdk~

執行以下命令(如果你這時候移動了目錄的位置,記得重新cd到這個目錄中,不要cd進解壓的目錄,不要cd進解壓的目錄,不要cd進解壓的目錄!!)
cd infer-*v0\.\1\.0 &&
echo "export PATH=\"\$PATH:`pwd`/infer/infer/bin\"" \ >> ~/.bash_profile &&
source ~/.bash_profile
這段命令包含了3個步驟,你看到有2個&&。
1、cd命令進入解壓的文件(所以我上面不讓你cd進去),如果出現No such file or directory了,那麼可能版本號問題,改吧改吧就可以了,cd中的*符號是通配符,這裏等價於osx-(linux64-),以至於Mac和linux都可以使用以上命令。
2、Mac自帶的shell是bash,所以這裏用echo將infer路徑寫入到.bash_profile文件中,弄過android sdk的都知道~
3、source是立即生效

執行完上面的命令後,只要不報錯就成功了,在終端輸入
infer -v
有返回版本號,則成功了

------GET START--------------------------
接下來使用官方提供的一個簡單的栗子來使用infer,你可以在終端使用infer命令來獲取錯誤反饋,並在修復後繼續執行來查看結果。
找到剛剛解壓出來的文件夾,在infer-osx-v0.1.0/infer/examples目錄,你會發現官方已經提供了幾個栗子,good job~
看examples目錄,你會發現有安卓項目、C語言文件、java類、oc類、IOS項目,沒錯啦,infer完全支持以上幾種類型的BUG分析。
這裏用ios_hello項目來進行演示。

首先用cd命令進入ios_hello目錄,然後運行以下命令
infer -- xcodebuild -target HelloWorldApp -configuration Debug -sdk iphonesimulator
裏面的HelloWorldApp是和你的項目名稱是一樣的
運行命令後你會看到大量的日誌(不是BUG列表),然後查看ios_hello目錄,會發現多了兩個文件夾
build and infer-out
我還沒研究build文件夾用來幹嘛的,意思是編譯的~
infer-out,則是輸出文件裏,bug列表就在裏面了。

FB還是很厚道的,用了4種格式存放BUG列表,自己選擇性使用吧。

然後讓我們看看內容,打開bugs.txt,方便快捷,查看第一段
/Users/roy/Desktop/debug/infer-osx-v0.1.0/infer/examples/ios_hello/HelloWorldApp/AppDelegate.m:20: error: MEMORY_LEAK
   memory dynamically allocated to shadowPath by call to CGPathCreateWithRect() at line 20, column 28 is not reachable after line 20, column 5

看描述,error:MEMORY_LEAK,內存泄漏,在AppDelegate.m文件20行28個字符處,shadowPath通過調用CGPathCreateWithRect方法動態分配了內存。
然後我們看看實際的代碼
-(void) memory_leak_bug {
    CGPathRef shadowPath = CGPathCreateWithRect(self.inputView.bounds, NULL);
}
soga!原因是沒有使用shadowPath,一般xcode也會發出警告~
繼續往下看(這裏我把錯誤日誌和代碼放在一起)
/Users/roy/Desktop/debug/infer-osx-v0.1.0/infer/examples/ios_hello/HelloWorldApp/AppDelegate.m:25: error: RESOURCE_LEAK
   resource acquired to fp by call to fopen() at line 25, column 8 is not released after line 25, column 5
--------------
-(void) resource_leak_bug {
    FILE *fp;
    fp=fopen("c:\\test.txt", "r"); //獲取文件對象,卻沒有使用
}
/Users/roy/Desktop/debug/infer-osx-v0.1.0/infer/examples/ios_hello/HelloWorldApp/AppDelegate.m:29: warning: PARAMETER_NOT_NULL_CHECKED
   Parameter callback is not checked for null, there could be a null pointer dereference: pointer callback could be null and is dereferenced at line 29, column 5
--------------------
-(void) parameter_not_null_checked_block_bug:(void (^)())callback {
    callback(); //參數沒有判斷爲nil,OMG~
}

後面還有很多日誌可以自行查閱,那麼我們接下來就修改一個bug,然後再次執行infer的檢查,看是不是會解決這個問題呢。
我們來解決這個獲取文件對象,卻沒有使用問題
-(void) resource_leak_bug {
    FILE *fp;
    fp=fopen("c:\\test.txt", "r");
    fclose(fp); //這裏加一個關掉
}
重新執行檢查,
infer -- xcodebuild -target HelloWorldApp -configuration Debug -sdk iphonesimulator
然後再次打開bus.txt(得把舊的關掉重新打開),發現
/Users/roy/Desktop/debug/infer-osx-v0.1.0/infer/examples/ios_hello/HelloWorldApp/AppDelegate.m:25: error: RESOURCE_LEAK
   resource acquired to fp by call to fopen() at line 25, column 8 is not released after line 25, column 5
已經不存在了,so good!!!

-----END---------------------
快速使用facebook infer的栗子就寫到這裏了,明天上班我會實際運用到正式項目當中,希望能有所收穫。
另外infer還有一系列的高級用法,有時間會慢慢寫出來。

最後,轉載請註明出處 : )

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章