infer 官方文档:https://fbinfer.com/
infer 是 facebook 开源的一款静态代码扫描工具(支持 objective-C、C++,Java 代码)
一.infer 安装
前提:需非 m1 芯片的电脑(自己 m1 芯片电脑尝试了很多种方法暂未安装成功,换了非 m1 芯片一安装就安装成功了)
一行命令即可完成安装:
brew install infer
安装后配置环境变量:
echo "export PATH=\"\$PATH:pwd/infer/infer/bin\"" \ >> ~/.bash_profile &&source ~/.bash_pr
其他安装 xcode 命令行工具
sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install
xcodebuild -version
(报错参考文章https://blog.csdn.net/li15809284891/article/details/79629190)
二.infer 命令使用(iphonesimulator 是模拟器编译,真机用 iphoneos 如:iphoneos14.5 )
第一种方式:Infer 提供了与 xcodebuild 的直接集成
【非 pod 项目】
infer run -- xcodebuild -target xx -configuration xx -sdk iphonesimulator
【pod 项目】
infer run -- xcodebuild -workspace xx.xcworkspace -scheme xx -configuration Debug -sdk iphonesimulator
第二种:最健壮的方法是生成一个编译数据库,然后将该数据库传递给 Infer
(我公司的项目第一种方式总报错,网上求助了大佬,告诉我用第二种方式)
1、先编译数据 database( -arch x86_64 COMPILER_INDEX_STORE_ENABLE=NO 参数可以不用加)
xcodebuild -workspace xx.xcworkspace -scheme xx -sdk iphonesimulator -arch x86_64 COMPILER_INDEX_STORE_ENABLE=NO| tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json
2、再执行 infer 指令
infer run --keep-going --skip-analysis-in-path Pods --compilation-database-escaped compile_commands.json
本人尝试这个 xcodebuild clean 命令,无法清除缓存,要使用下面的命令
xcodebuild -scheme xx -workspace xx.xcworkspace clean
三、生成报告
扫描后执行
infer-explore --html
四、工作流程
PS:不管是分析哪种语言,Infer 运行时,分为两个主要阶段:
1.捕获阶段:Infer 捕获编译命令,将文件翻译成 Infer 内部的中间语言
这就是我们调用 Infer 时带上一个编译命令的原因了,比如: infer -- clang -c file.c结果就是文件照常编译,同时被 Infer 翻译成中间语言,留作第二阶段处理。特别注意的就是,如果没有文件被编译,那么也没有任何文件会被分析。
2.分析阶段:Infer 分析 infer-out/ 下的所有文件。分析时,会单独分析每个方法和函数。
在分析一个函数的时候,如果发现错误,将会停止分析,但这不影响其他函数的继续分析。
错误除了会显示在标准输出之外,还会输出到文件 infer-out/bug.txt 中,我们过滤这些问题,仅显示最有可能存在的。
默认情况下,每次运行 infer 命令都会删除之前的 infer-out 文件夹。你可以通过 --incremental 参数使用增量模式。增量模式下,运行 infer 命令不会删除 infer-out 文件夹,但是会利用这个文件夹进行 diff,减少分析量。一般进行全新一轮分析时直接使用默认的非增量模式,而对于只想分析修改部分情况时,就使用增量模式。
五、增量&非增量
增量模式和非增量模式
六、添加过滤文件
第一种,分析带 cocoapods 的项目,在工程目录下新建 .inferconfig 文件
{
"skip-analysis-in-path":["Pods"]
}
{
"infer-whitelist-path-regex":[
],
"infer-blacklist-path-regex":[
"Pods/AFNetworking",
"Pods/SDWebImage"
]
}
第二种,在命令行里添加过滤条件
1.in-path 后面跟的是一个忽略文件或者文件夹的路径数组
2.["Pods"] 代表过滤所有的 Pods 文件
3.["Pods/AFNetworking","Pods/Masonry"] 代表过滤 AFNetworking、Masonry 三方库
4.也可以写个脚本对解析出来的文件进行二次拆分,按组件模块、错误和警告划分
--skip-analysis-in-path Pods
================================================================
PS: 遇到的坑
1.使用 m1 芯片的电脑安装 infer,无法安装成功
解决办法:换成非 m1 芯片的 mac 本,成功解决
2.使用
infer run -- xcodebuild -workspace xx.xcworkspace -scheme xx -configuration Debug -sdk iphonesimulator
命令会报错,报错如下
xternal Error: *** capture failed to execute: exited with code 65
Error backtrace:
Raised at Stdlib.input_line.scan in file "stdlib.ml", line 449, characters 14-31
Called from Stdio__In_channel.input_line_exn in file "src/in_channel.ml" (inlined), line 68, characters 13-30
Called from IBase__Utils.with_channel_in in file "src/base/Utils.ml", line 260, characters 11-44
Re-raised at IBase__Die.raise_error.do_raise in file "src/base/Die.ml", line 26, characters 8-56
Called from Integration__Driver.capture in file "src/integration/Driver.ml", line 145, characters 6-36
Called from IBase__Utils.timeit in file "src/base/Utils.ml", line 429, characters 16-20
Called from IBase__ScubaLogging.execute_with_time_logging in file "src/base/ScubaLogging.ml", line 79, characters 29-44
Called from Backend__GCStats.log_f in file "src/backend/GCStats.ml", line 90, characters 10-14
Called from Dune__exe__Infer.run in file "src/infer.ml", line 20, characters 2-36
Called from IBase__Utils.timeit in file "src/base/Utils.ml", line 429, characters 16-20
Called from IBase__ScubaLogging.execute_with_time_logging in file "src/base/ScubaLogging.ml", line 79, characters 29-44
Called from Dune__exe__Infer.run in file "src/infer.ml", line 25, characters 22-94
Run the command again with `--keep-going` to try and ignore this error.
69324: Error while running epilogue "Stop Sqlite write daemon":
(Unix.Unix_error "No such file or directory" connect
"((addr (ADDR_UNIX sqlite_write_socket)))").
解决办法:使用第二种生成中间数据库的方式,解决(见上文)
3.无法用模拟器生成 database 文件,可以用真机命令生成
解决办法:
4.执行过程中 找不到报 arm64
解决办法:
5.报 '-index-store-path' 错误
Error message:clang-8: error: unknown argument: '-index-store-path'*** Infer needs a working compilation command to run.
clang-8: error: unknown argument: '-index-store-path'
网上的解决办法: 由于从 Xcode 9.0 开始将-index-store-path 参数添加到构建命令中。而 infer 所依赖的 clang 还不支持此参数。在项目 Build Setting 中搜索 index 并将 Enable Index-While-Building Functionality 选项设置为 NO
我这边采用网上的解决办法不生效,于是在生成中间文件的时候加了 COMPILER_INDEX_STORE_ENABLE=NO 的参数就解决了
6.第一次能扫出来全的报告(生成的 compile_commands.json 也比较全),第二次执行时输入 xcodebuild clean 后,在手动删除 inferout 文件夹、xcodebuild.log、build、compile_commands.json 在依次运行命令,扫出来的问题不全(生成的 compile_commands.json 明显很少,好像有缓存没清除掉)
解决办法:不要用 xcodebuild clean ,改为下面的
xcodebuild -scheme xx -workspace xx.xcworkspace clean
jenkins 进行 infer 静态扫描,给工作群发送报告通知
https://testerhome.com/topics/30912