静态分析工具用于直接扫描代码,通过对代码的分析找出诸如内存泄漏或缓冲区溢出等常见的已知错误和漏洞。商用专业的静态代码分析工具还可以按照指定的编码标准进行扫描分析。
在正规的开发中CI/CD过程会加入静态代码分析用于预先防范代码漏洞,在一般的开发编码过程中也可以使用静态代码分析工具帮助我们查找编码的疏漏。Zephyr v3.3.0开始引入了对静态编码工具(Static Code Analysis 后面简称SCA)的支持,在使用west构建时SCA同时工作进行代码扫描,并提示错误
Zephyr原生支持的SCA
Zephyr原生支持sparse作为自己的SCA,只用在构建的时候通过ZEPHYR_SCA_VARIANT
指定spare
即可,具体方法如下1
west build -b mm_feather zephyr/samples/hello_world -- -DZEPHYR_SCA_VARIANT=sparse
构建+过程中可能会提示找不到cgcc
,这是因为没有安装sparse, ubuntu下执行下面命令进行安装1
sudo apt-get install sparse
sparse是linus为kernel开发的一个静态代码分析工具,其核心功能有限,主要用于检查不同地址空间指针的混用。
https://www.kernel.org/doc/html/latest/dev-tools/sparse.html
SCA工具的支持和添加
Zephyr通过cmake完成对SCA工具的集成和支持,主要的内容在如下文件/文件夹中,可以通过查找关键字SPARSE
, SCA_ROOT
, ZEPHYR_SCA_VARIANT
找到相关内容cmake/modules/FindDeprecated.cmake
cmake/modules/FindScaTools.cmake
cmake/modules/kernel.cmake
cmake/modules/root.cmake
cmake/sca/sparse/
对sparse的原生支持
对sparse的支持通过cmake/sca/sparse
来指定,可以通过修改其sca.cmake来改变配置
SCA工具的添加
对 SCA 工具的支持在sca.cmake 文件中实现。 该文件放在<SCA_ROOT>/cmake/sca/<tool>/sca.cmake
。 Zephyr 默认将自己的代码目录做为SCA_ROOT, 我们新加SCA tool也可以放在zephyr/cmake/sca
下
例如要添加cppcheck作为sca
1 建立cppcheck1
2
3
4
5zephyr/ # zephyr代码目录
└── cmake/
└── sca/
└── cppcheck/ # SCA工具名, 构建时提供给 ZEPHYR_SCA_VARIANT
└── sca.cmake # sca 工具配置
实际项目中为了不污染zephyr的代码目录,我们会另外指定路径1
2
3
4
5/mnt/g/project/zephyrproject/sca # 自定义的SCA_ROOT, 构建时指定
└── cmake/
└── sca/
└── cppcheck/ # SCA工具名, 构建时提供给 ZEPHYR_SCA_VARIANT
└── sca.cmake # sca 工具配置
2 配置cppcheck
sca.cmake的内容如下1
2
3
4
5
6
7
8
9find_program(CPPCHECK_TOOL cppcheck)
set(CMAKE_C_CPPCHECK
${CPPCHECK_TOOL}
--enable=warning
--inconclusive
--force
--inline-suppr
CACHE INTERNAL ""
)
3 运行&结果
指定ZEPHYR_SCA_VARIANT为cppcheck,同时因为配置文件放到外部文件夹需要做SCA_ROOT指定1
west build -b mm_feather zephyr/samples/hello_world -- -DZEPHYR_SCA_VARIANT=cppcheck -DSCA_ROOT=/mnt/g/project/zephyrproject/sca
我们的示例代码main.c为1
2
3
4
5
6
7
void main(void)
{
int a[5];
a[5] = 32;
printk("Hello World! %s\n", CONFIG_BOARD);
}
构建过程中会提示, 可以看到会指出数组a操作出界1
2
3
4
5
6
7Checking /mnt/g/project/zephyrproject/zephyr/samples/hello_world/src/main.c: BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024;CPU_MIMXRT1062DVL6A=1;KERNEL=1;NDEBUG=1;XIP_BOOT_HEADER_DCD_ENABLE=1;XIP_BOOT_HEADER_ENABLE=1;XIP_EXTERNAL_FLASH=1;__PROGRAM_START=1;__ZEPHYR__=1;_ASMLANGUAGE...
Checking /mnt/g/project/zephyrproject/zephyr/samples/hello_world/src/main.c: BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024;CPU_MIMXRT1062DVL6A=1;KERNEL=1;NDEBUG=1;XIP_BOOT_HEADER_DCD_ENABLE=1;XIP_BOOT_HEADER_ENABLE=1;XIP_EXTERNAL_FLASH=1;__PROGRAM_START=1;__ZEPHYR__=1;_ASMLANGUAGE;__ASSEMBLER__...
/mnt/g/project/zephyrproject/zephyr/samples/hello_world/src/main.c:12:3: error: Array 'a[5]' accessed at index 5, which is out of bounds. [arrayIndexOutOfBounds]
a[5] = 32;
^
[5/14] Linking C static library app/libapp.a
[6/14] Linking C executable zephyr/zephyr_pre0.elf
参考
https://docs.zephyrproject.org/latest/develop/sca/index.html