介绍

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的类型有:

  1. buffer overflow //BUG几率很高
  2. we previously assumed ‘xxx’ could be null //可能误报,因为smatch可能没法检查变量已经在别的函数赋值了,需要详细检查确认
  3. testing array offset ‘xxx’ after use. //函数的入参没有测试就作数组下标
  4. potential null dereference ‘xxx’ //空指针,但在log里没发现
  5. 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

  1. possible memory leak of ‘xxx’ //可能内存泄漏
  2. always true condition //总是为真
  3. for statement not indented // for 循环没有缩进

Logo

更多推荐