介绍
Smatch is a static analysis tool for C. Most of the checks are for the linux kernel. Smatch 分析程序代码的逻辑错误。它可以检测到诸如“为一个没锁上的 spinlock 执行解锁”的逻辑错误。所以提前修复一些代码中隐含的BUG是很有必要的。
官方:
http://smatch.sourceforge.net/
Smatch需要自己下载和编译:
git clone git://repo.or.cz/smatch.git
cd smatch; make clean all
但是有可能会遇到一些编译问题,如对库的依赖 libxml, libgtk2, llvm-3.0, libsqlite3-dev,或许你还要更新你的源。
sudo apt-get install libsqlite3-dev
安装完llvm-3.0后,再修改smatch/Makefile llvm-config -> llvm-config-3.0
使用
C=1是只check重新编译的,C=2是所有代码都check.
make -j32 CHECK="/home/tools/smatch/smatch/smatch" C=2 > smatch_kernel.log 2>&1
分析
一般有info, warn, error三种提示,我们重点关注mediatek代码里的error case.
error:
$cat smatch_kernel.log | grep error | wc -l
624
$cat smatch_kernel.log | grep error > _smatch_kernel_error.log
打开error.log来看,发现有一种case特别多“error: directive in argument list”
$cat smatch_kernel_error.log | grep “error: directive in argument list” | wc -l
455
简单看了下,就是 一个宏定义函数里的参数又使用了条件编译宏,这是一个non-issue,只是语法上的问题,可以忽略。LKML有讨论:https://lkml.org/lkml/2013/11/17/136
例如:
PRINTK("%s\n",
#ifdef FOO
"foo"
#endif
#ifdef BAR
"bar"
#endif
"string");
忽略“error: directive in argument list”
$grep -v “error: directive in argument list” ./smatch_kernel_error.log > ./smatch_kernel_error2.log
error的类型有:
- buffer overflow //BUG几率很高
- we previously assumed ‘xxx’ could be null //可能误报,因为smatch可能没法检查变量已经在别的函数赋值了,需要详细检查确认
- testing array offset ‘xxx’ after use. //函数的入参没有测试就作数组下标
- potential null dereference ‘xxx’ //空指针,但在log里没发现
- snprintf() chops off the last chars of ‘info->name’: 80 vs 64 //输入的数据长度大于储存的长度,可能导致数据丢失
…
warn:
$cat smatch_kernel.log | grep “warn:” | wc -l
407
$cat smatch_kernel.log | grep “warn:” > ./smatch_kernel_warn.log
- possible memory leak of ‘xxx’ //可能内存泄漏
- always true condition //总是为真
- for statement not indented // for 循环没有缩进
…