Linux 静态代码检查工具:sparse 的安装和使用

sparse 是用于 C 语言的语法分析器,用以对 C 代码进行静态检查,它不但可以检查 ANSI C 而且还能检查具有 gcc 扩展的 C 。在 Linux 中,不但可以检查用户端代码,还可以检查内核代码。起初它由 Linus 编写,后来交给其他人维护。

获得一个新的sparse:

$ git clone git://git.kernel.org/pub/scm/devel/sparse/sparse.git

官方文档:
Documentation/dev-tools/sparse.rst
https://linux.die.net/man/1/sparse

LWN.net article: http://lwn.net/Articles/87538/

编译方法:

cd sparse; make; make install

由于kernel默认使用Sparse的@ top Makefile:

CHECK = sparse

CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__
-Wbitwise -Wno-return-void $(CF)

所以在内核编译时,只要 make C=1/2 就可以了。
make C=1 会检查被编译的文件。
make C=2 会检查所有文件,不管是否被编译。

编译后,检查报告即可:

$ make -j4 C=2 > PORJECT_sparse_kernel_error.log 2>&1

$ cat ./PORJECT_sparse_kernel.log | grep “error:” | cut -d ‘:’ -f4- | sort | uniq -c | sort -g -r > PORJECT_sparse_kernel_error.log

PORJECT检测到的错误类型:

    455  error: directive in argument list
     42  error: incompatible types in comparison expression (different type sizes)
     32  error: Expected ; at end of declaration
     31  error: bad integer constant expression
     19  error: cannot dereference this type
     16  error: got +=
     14  error: got buf
     13  error: return with no return value
     13  error: incompatible types in comparison expression (different signedness)
     13  error: Expected ) in function declarator
     12  error: cannot size expression
      8  error: got -=
      7  error: Trying to use reserved word 'break' as identifier
      5  error: Trying to use reserved word 'case' as identifier
      5  error: got }
      5  error: Expected ; at the end of type declaration
      4  error: return expression in void function
      3  error: Trying to use reserved word 'return' as identifier
      3  error: marked inline, but without a definition
      3  error: incompatible types for operation (<)
      2  error: Trying to use reserved word 'if' as identifier
      2  error: too many errors
      2  error: subtraction of different types can't work (different address spaces)
      2  error: incompatible types for operation (!=)
      2  error: incompatible types for operation (<=)
      2  error: got 3
      2  error: got 2
      2  error: got ==
      2  error: dubious one-bit signed bitfield
      1  error: symbol 'panic' redeclared with different type (originally declared at /home/project/PORJECT/kernel/include/linux/kernel.h:208) - different modifiers
      1  error: symbol 'mtk_wcn_stp_psm_notify_stp' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/kernel/drivers/conn_soc/common/core/../core/include/stp_core.h:504) - incompatible argument 1 (different signedness)
      1  error: symbol 'mt_get_chip_sw_ver' redeclared with different type (originally declared at /home/project/PORJECT/kernel/../mediatek/platform/mt6752/kernel/core/include//mach/mt_boot.h:58) - different signedness
      1  error: symbol '__module_put_and_exit' redeclared with different type (originally declared at /home/project/PORJECT/kernel/include/linux/module.h:449) - different modifiers
      1  error: symbol 'lcm' redeclared with different type (originally declared at /home/project/PORJECT/kernel/include/linux/lcm.h:6) - different modifiers
      1  error: symbol 'kbase_pm_register_inuse_cores' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/platform/mt6752/kernel/drivers/gpu/mali/drivers/gpu/arm/midgard/mali_kbase_pm_policy.h:224) - different signedness
      1  error: symbol 'gcd' redeclared with different type (originally declared at /home/project/PORJECT/kernel/include/linux/gcd.h:6) - different modifiers
      1  error: symbol 'g_call_state' redeclared with different type (originally declared at /home/project/PORJECT/kernel/../mediatek/kernel/include//mach/battery_common.h:185) - different signedness
      1  error: symbol 'dprec_logger_trigger' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/platform/mt6752/kernel/drivers/dispsys/display_recorder.h:145) - incompatible argument 1 (different signedness)
      1  error: symbol 'dprec_logger_submit' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/platform/mt6752/kernel/drivers/dispsys/display_recorder.h:155) - incompatible argument 1 (different signedness)
      1  error: symbol 'dprec_logger_start' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/platform/mt6752/kernel/drivers/dispsys/display_recorder.h:146) - incompatible argument 1 (different signedness)
      1  error: symbol 'dprec_logger_done' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/platform/mt6752/kernel/drivers/dispsys/display_recorder.h:147) - incompatible argument 1 (different signedness)
      1  error: symbol 'do_exit' redeclared with different type (originally declared at /home/project/PORJECT/kernel/include/linux/kernel.h:214) - different modifiers
      1  error: symbol 'crc32_le' redeclared with different type (originally declared at /home/project/PORJECT/kernel/include/linux/crc32.h:11) - different modifiers
      1  error: symbol '__crc32c_le' redeclared with different type (originally declared at /home/project/PORJECT/kernel/include/linux/crc32.h:14) - different modifiers
      1  error: symbol 'crc32_be' redeclared with different type (originally declared at /home/project/PORJECT/kernel/include/linux/crc32.h:12) - different modifiers
      1  error: symbol 'complete_and_exit' redeclared with different type (originally declared at /home/project/PORJECT/kernel/include/linux/kernel.h:216) - different modifiers
      1  error: symbol '_bin2bcd' redeclared with different type (originally declared at /home/project/PORJECT/kernel/include/linux/bcd.h:20) - different modifiers
      1  error: symbol '_bcd2bin' redeclared with different type (originally declared at /home/project/PORJECT/kernel/include/linux/bcd.h:19) - different modifiers
      1  error: incompatible types in comparison expression (different address spaces)
      1  error: incompatible types for operation (==)
      1  error: got 0
      1  error: got \
      1  error: Expected ) in function call

[分析]

     455 error: directive in argument list      //语法问题,non-issue.
     32  error: Expected ; at end of declaration           //使用了__restrict__,优化编译器的限定符引起的误报
     19  error: incompatible types in comparison expression (different type sizes)  //fixed
     16  error: got +=           //使用了__restrict__,优化编译器的限定符引起的误报
     14  error: got buf        //使用了__restrict__,优化编译器的限定符引起的误报
     13  error: return with no return value  //有些是误报,没有明显逻辑错误,暂时不改
     13  error: incompatible types in comparison expression (different signedness)  //fixed
     13  error: Expected ) in function declarator   //使用了__restrict__,优化编译器的限定符引起的误报
      8  error: got -=           //使用了__restrict__,优化编译器的限定符引起的误报
      7  error: Trying to use reserved word 'break' as identifier    //使用了__restrict__,优化编译器的限定符引起的误报
      5  error: Trying to use reserved word 'case' as identifier      //使用了__restrict__,优化编译器的限定符引起的误报
      5  error: got }           //使用了__restrict__,优化编译器的限定符引起的误报
      5  error: Expected ; at the end of type declaration     //使用了__restrict__,优化编译器的限定符引起的误报
      3  error: Trying to use reserved word 'return' as identifier   //使用了__restrict__,优化编译器的限定符引起的误报
      3  error: incompatible types for operation (<) //误报
      2  error: Trying to use reserved word 'if' as identifier             //使用了__restrict__,优化编译器的限定符引起的误报
      2  error: subtraction of different types can't work (different address spaces)     // 使用了__user限定符的指针page和指向page的的指针ptr作运算,误报说不同地址空间不能作运算
      2  error: return expression in void function         //void函数return 0, 不需要改
      2  error: marked inline, but without a definition     //focaltech_driver  驱动close api 声明inline 但实现没有inline,TP一般不会close,也没有逻辑性问题,暂时不改
      2  error: incompatible types for operation (<=)   //误报,void __iomem * p   使用__iomem时,告诉编译器忽略对变量的检查,但Smatch/Sparse不知道
      2  error: got 3              //使用了__restrict__,优化编译器的限定符引起的误报
      2  error: got 2              //使用了__restrict__,优化编译器的限定符引起的误报
      2  error: got ==           //使用了__restrict__,优化编译器的限定符引起的误报
      1  error: too many errors   //使用了__restrict__,优化编译器的限定符引起的误报
      1  error: symbol 'mtk_wcn_stp_psm_notify_stp' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/kernel/drivers/conn_soc/common/core/../core/include/stp_core.h:504) - incompatible argument 1 (different signedness)     //声明使用UINT32 , 实现使用MTKSTP_PSM_ACTION_T enum,忽略
      1  error: symbol 'mt_get_chip_sw_ver' redeclared with different type (originally declared at /home/project/PORJECT/kernel/../mediatek/platform/mt6752/kernel/core/include//mach/mt_boot.h:58) - different signedness //使用了__weak 限定符,误报
      1  error: symbol 'kbase_pm_register_inuse_cores' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/platform/mt6752/kernel/drivers/gpu/mali/drivers/gpu/arm/midgard/mali_kbase_pm_policy.h:224) - different signedness   //无逻辑错误,忽略
      1  error: symbol 'g_call_state' redeclared with different type (originally declared at /home/project/PORJECT/kernel/../mediatek/kernel/include//mach/battery_common.h:185) - different signedness  //无逻辑错误,忽略
      1  error: symbol 'dprec_logger_trigger' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/platform/mt6752/kernel/drivers/dispsys/display_recorder.h:145) - incompatible argument 1 (different signedness)   //无逻辑错误,忽略
      1  error: symbol 'dprec_logger_submit' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/platform/mt6752/kernel/drivers/dispsys/display_recorder.h:155) - incompatible argument 1 (different signedness)   //无逻辑错误,忽略
      1  error: symbol 'dprec_logger_start' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/platform/mt6752/kernel/drivers/dispsys/display_recorder.h:146) - incompatible argument 1 (different signedness)    //无逻辑错误,忽略
      1  error: symbol 'dprec_logger_done' redeclared with different type (originally declared at /home/project/PORJECT/kernel/mediatek/platform/mt6752/kernel/drivers/dispsys/display_recorder.h:147) - incompatible argument 1 (different signedness)   //无逻辑错误,忽略
      1  error: incompatible types in comparison expression (different address spaces)   //误报
      1  error: incompatible types for operation (!=)   //非指针和NULL 比较,语法问题,暂时不改
      1  error: incompatible types for operation (==)  //extern vramsize;   没有指定类型,然后if(vramsize == 0), fixed
      1  error: got 0   //使用了__restrict__,优化编译器的限定符引起的误报
      1  error: got \   //使用了__restrict__,优化编译器的限定符引起的误报
      1  error: Expected ) in function call   //使用了__restrict__,优化编译器的限定符引起的误报
      1  error: cannot size expression         //使用了__restrict__,优化编译器的限定符引起的误报
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值