#盲盒+码# Clang Static Analyzer (1) scan-build

时间:2022-12-08 15:59:51

1、Clang Static Analyzer介绍

Clang 静态分析器CSA是一个源代码分析工具,可查找 C、C++ 和 Objective-C 程序的bugs。 目前可以从命令行中运行,或者如果您使用 macOS,则可以在 Xcode 中使用。当从命令行中运行时,该工具和代码构建串联运行。 该分析器是100%开源的,是Clang项目的一部分。类似Clang的其他工具,它实现为C++库,可以被其他工具和应用调用。

2、Clang Static Analyzer命令行工具

静态分析器在设计上是一个 GUI 工具。其目的是找到程序中的错误执行路径,这些路径很难通过查看非交互式标准输出进行获取。但是,可以从命令行调用静态分析器来获取分析结果,稍后在图形界面中以交互方式查看分析结果。以下两个工具通常用于从命令行运行分析器,这两种工具都是封装的脚本,用于分析结果、调用底层的Clang编译器:

  • Scan-Build是一个古老而简单的命令行工具,可在编译项目时输出HTML文件。用于查看静态分析器警告。您可以在 Web 浏览器中查看分析结果。
    • 对于只想在办公桌上或在非常简单的协作环境中查看静态分析结果的个人开发人员非常有用。
    • 适用于所有主要平台(Windows,Linux,macOS),并且在许多Linux发行版中作为软件包提供。
    • 不包括对交叉翻译单元分析的支持cross-translation-unit analysis。
  • CodeChecker是一个 Web 服务器,它按需在项目上运行静态分析器,并维护问题数据库。
    • 非常适合在协作环境中管理大量静态分析器警告。
    • 通常比scan-build功能更丰富。
    • 支持增量分析:结果可以存储在数据库中,后续分析运行可以对比,列出新添加的缺陷。
    • 通过 CodeChecker 在 Linux 上完全支持交叉翻译单元 (Cross Translation Unit ,CTU) 分析。
    • 也可以运行clang-tidy checker检查器。
    • 开源,但是开源项目之外,即不是LLVM项目的一部分。

3、scan-build工具

使用scan-build工具的时候,在项目代码构建期间,所有的源代码文件被编译,也通过串联的方式同事被静态分析器分析。在编译完成时,分析结果可以在Web浏览器里展示给用户。

scan-build不了解如何构建代码,它是如何工作的呢?它会替代CC和CXX环境变量来改变构建,使用一个fake假的编译器来替代那个正常编译项目的编译器。假的编译器执行clang或gcc(取决于平台)来编译代码,然后执行静态分析来分析项目代码。

对于OpenHarmony项目,执行命令sudo bash build/prebuilts_download.sh的时候,会安装clang工具,其中就包含scan-build,位置在:openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/scan-build。当然,自己安装llvm clang的时候也会安装该工具,命令如下:

sudo apt-get install llvm
sudo apt-get install clang
sudo apt-get install libblocksruntime-dev

4、简单示例

提供一个简单的示例文件simple.c,里面包含明显的错误。

#include <stdio.h>

struct S {
  int x;
};

void f(struct S s){
}

void test() {
  struct S s;
  f(s); // warn
}

int test2(int x){
  return 5/(x-x); // warn
}

int main(){
  test();
  test2(532);
  printf("Hej\r\r");
}

运行如下命令来生成分析结果,可以使用scan-build --help来查看更多的使用帮助信息。

~/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/scan-build -v gcc -o simple simple.c

输出如下,可以看到我们发现了一个除零告警。输出结果保存在目录/tmp/scan-build-2022-12-05-200835-24590-1,也可以通过-o dir选项指定目录。

zhushangyuan@DESKTOP-RPE9R4O:~/CSA$ ~/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/scan-build -v gcc -o simple simple.c
scan-build: Using '/home/zhushangyuan/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang-12' for static analysis
scan-build: Emitting reports for this run to '/tmp/scan-build-2022-12-05-200835-24590-1'.
simple.c: In function ‘test2’:
simple.c:16:11: warning: division by zero [-Wdiv-by-zero]
   return 5/(x-x); // warn
          ~^~~~~~
simple.c:16:11: warning: Division by zero [core.DivideZero]
  return 5/(x-x); // warn
         ~^~~~~~
1 warning generated.
scan-build: Analysis run complete.
scan-build: 1 bug found.
scan-build: Run 'scan-view /tmp/scan-build-2022-12-05-200835-24590-1' to examine bug reports.

然后执行命令~/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/scan-view /tmp/scan-build-2022-12-05-200835-24590-1会自动打开一个浏览器来展示分析结果。如下图:

#盲盒+码# Clang Static Analyzer (1) scan-build

点击每一条分析结果右侧的View Report链接,可以查看分析结果的详细信息,如下图,可以看出函数调用关系以及代码缺陷。

#盲盒+码# Clang Static Analyzer (1) scan-build

5、Makefile构建

对于单个文件比较简单,如果使用其他构建系统,比如Make和Makefile,我们来看下如何运行静态分析的。创建个Makefile,如下:

all: simple.c
	gcc -o simple_mk simple.c
clean:
	rm -f *.o simple_mk
	

在包含simple.c和Makefile的目录下,在命令行终端里执行make命令就可以执行编译。然后执行命令scan-build make就应该可以边构建边分析。不幸的是,并不行,如下文出现的字样Removing directory ... because it contains no reports. 这原因就是上文说过的,scan-build会提到CC或CXX环境变量,但是这个Makefile里并没有CC变量。

zhushangyuan@DESKTOP-RPE9R4O:~/CSA$ ~/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/scan-build make
scan-build: Using '/home/zhushangyuan/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang-12' for static analysis
gcc -o simple_mk simple.c
simple.c: In function ‘test2’:
simple.c:16:11: warning: division by zero [-Wdiv-by-zero]
   return 5/(x-x); // warn
          ~^~~~~~
scan-build: Analysis run complete.
scan-build: Removing directory '/tmp/scan-build-2022-12-05-201925-24638-1' because it contains no reports.
scan-build: No bugs found.

我们再写个使用CC变量的Makefile_CC,如下。执行make -f Makefile_CC可以编译构建。

CC=gcc
all: simple.c
	$(CC) -o simple_mk simple.c
clean:
	rm -f *.o simple_mk

再使用scan-build构建分析试试,如下。这次就可以了。

zhushangyuan@DESKTOP-RPE9R4O:~/CSA$ ~/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/scan-build make -f Makefile_CC
scan-build: Using '/home/zhushangyuan/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang-12' for static analysis
/home/zhushangyuan/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/../libexec/ccc-analyzer -o simple_mk simple.c
simple.c: In function ‘test2’:
simple.c:16:11: warning: division by zero [-Wdiv-by-zero]
   return 5/(x-x); // warn
          ~^~~~~~
simple.c:16:11: warning: Division by zero [core.DivideZero]
  return 5/(x-x); // warn
         ~^~~~~~
1 warning generated.
scan-build: Analysis run complete.
scan-build: 1 bug found.
scan-build: Run 'scan-view /tmp/scan-build-2022-12-05-202514-24656-1' to examine bug reports.

6、OpenHarmony工程构建

使用scan-build hb build是不行的,也会输出信息:Removing directory ... because it contains no reports.。这是因为OpenHarmony构建的时候,也是没有设置CC环境或CXX环境变量,所以是无法使用scan-build工具的。

和make、ninja这些元构建系统应该是没有关系的,只要有CC和CXX这些环境变量就行。简单尝试了下openharmony\third_party\gn\examples\simple_build这个gn+ninja构建项目也是不可以的,因为没有需要的环境变量。

但是也不需要灰心,下次会介绍如何CodeChecker来对OpenHarmony项目代码进行静态代码分析。

7、参考站点

本文作者:zhushangyuan_

想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com/#bkwz​