0


【工具推荐】CppCheck:C/C++静态代码检测工具的使用教程和实战案例,提前发现隐患,让你的代码更安全

CppCheck 是一款强大的静态代码分析工具,可以大幅提升C/C++代码的质量和安全性。通过安装和使用CppCheck,可以提前发现潜在的问题,减少Bug和漏洞的产生。同时,将CppCheck集成到CI/CD管道中,可以实现持续化代码检测,确保代码库始终保持高质量。希望本文对你了解和使用CppCheck有所帮助,让你的代码更加安全可靠。

在这里插入图片描述


🧑 博主简介:现任阿里巴巴嵌入式技术专家,15年工作经验,深耕嵌入式+人工智能领域,精通嵌入式领域开发、技术管理、简历招聘面试。CSDN优质创作者,提供产品测评、学习辅导、简历面试辅导、毕设辅导、项目开发、C/C++/Java/Python/Linux/AI等方面的服务,如有需要请站内私信或者联系任意文章底部的的VX名片(ID:

gylzbk

💬 博主粉丝群介绍:① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。③ 群内也有职场精英,大厂大佬,可交流技术、面试、找工作的经验。④ 进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬。⑤ 进群赠送CSDN评论防封脚本,送真活跃粉丝,助你提升文章热度。有兴趣的加文末联系方式,备注自己的CSDN昵称,拉你进群,互相学习共同进步。

在这里插入图片描述

【工具推荐】CppCheck:C/C++静态代码检测工具的使用教程和实战案例,提前发现隐患,让你的代码更安全

概述

在软件开发过程中,代码的质量和安全性是至关重要的。特别是在C和C++这样容易出现低级错误的语言中,代码静态分析工具如CppCheck显得尤为重要。CppCheck是一款开源的C/C++静态代码分析工具,它能帮助开发者查找潜在的问题,确保代码的质量和安全性。本文将介绍CppCheck的功能、安装、使用方法及其在提升代码质量方面的重要作用。

什么是CppCheck?

CppCheck是一款专门针对C和C++代码的静态分析工具。与传统编译器不同,CppCheck可以捕获到更多潜在的错误和编码不规范之处,通过对代码进行深入分析,帮助开发者识别出:

  • 潜在的内存泄漏
  • 未初始化的变量
  • 可疑的逻辑错误
  • 代码中的资源泄漏
  • 非常见的编程错误与漏洞

安装CppCheck

CppCheck支持多个平台(Windows、Linux、macOS)。这里分别介绍在不同平台上的安装方法。

Windows

在Windows上,可以通过安装程序安装CppCheck。

  1. 访问 CppCheck的官方网站。
  2. 下载适合Windows的安装包(通常以.exe结尾)。
  3. 双击安装包,按照提示完成安装。

Linux

在大多数Linux发行版上,可以直接通过包管理器安装CppCheck。

Debian/Ubuntu

sudoapt-get update
sudoapt-getinstall cppcheck

CentOS/Fedora

sudo yum install cppcheck

其他发行版

可以通过源码安装,具体步骤如下:

git clone https://github.com/danmar/cppcheck.git
cd cppcheck
makeSRCDIR=build CFGDIR=cfg HAVE_RULES=yes
sudomakeinstall

macOS

在macOS上,可以使用Homebrew安装CppCheck。

brew install cppcheck

CppCheck使用教程

安装完成后,就可以使用CppCheck对C/C++代码进行静态分析了。

基本用法

最基本的用法是对单个源文件进行检测:

cppcheck example.c

对整个项目目录进行检测:

cppcheck /path/to/project

生成HTML格式的报告

CppCheck可以生成HTML格式的报告,更方便查看和分享。

cppcheck --enable=all --xml --xml-version=2.2> result.xml
cppcheck-htmlreport --file=result.xml --report-dir=cppcheck-report --source-dir=.

常用选项

  • --enable=all:启用所有类型的检查,包括样式、性能、可移植性等。
  • --inconclusive:显示可能存在但不确定的问题。
  • --force:对所有文件进行检查,即使它们通常不会单独编译。
  • --std=c++11:指定C++标准(例如:C++11、C++14、C++17)。
  • --suppressions-list=suppressions.txt:指定一个文件列表,包含要忽略的特定检测规则。

示例

对一个包含多个文件的项目进行全面检查:

cppcheck --enable=all --inconclusive--std=c++11 /path/to/project

如果你想忽略某些特定的警告,可以使用

--suppress

选项。假设你想忽略所有关于未使用变量的警告:

cppcheck --enable=all --suppress=unusedVariable /path/to/project

集成到CI/CD管道

CppCheck可以很好地集成到CI/CD管道中,例如Jenkins、GitLab CI等。这确保在每次代码提交和合并请求时,自动执行代码静态分析,提前发现问题。

GitLab CI 示例

在GitLab CI中,可以编写一个简单的

.gitlab-ci.yml

文件:

stages:- analyze

cppcheck:stage: analyze
  script:- cppcheck --enable=all --xml --xml-version=2 . 2> cppcheck.xml
  artifacts:reports:codequality: cppcheck.xml

cppcheck实战演示

问题代码

#include<stdio.h>#include<stdlib.h>#include<string.h>intexampleFunction(){printf("%s enter\n",__func__);int array[10];int index =10;
    array[index]=42;// 数组越界访问printf("%s leave\n",__func__);return0;}intexampleFunction1(){int value;// 变量未初始化printf("%s enter\n",__func__);if(value ==0){printf("value is 0");}else{printf("value not 0");}printf("%s leave\n",__func__);return0;}intexampleFunction2(){char*buffer =NULL;printf("%s enter\n",__func__);

    buffer =malloc(10);//buffer申请的内存没有释放strcpy(buffer,"haha");printf("%s leave\n",__func__);return0;}intmain(int argc,char*argv[]){exampleFunction();exampleFunction1();exampleFunction2();return0;}

如上所示,代码包含了三个函数:

exampleFunction

exampleFunction1

exampleFunction2

,以及一个

main

函数来调用它们。
下面是该程序编译运行的结果:
在这里插入图片描述
可以发现,该程序运行过程中出现了异常,被终止运行了。

实际上,这3个函数每一个函数都有其独特的问题,这些问题就可以通过静态代码扫描工具在编译前发现。下面我将逐一解释每个函数的问题,并展示

cppcheck

扫描到的结果。

问题1:数组越界

exampleFunction

这个函数试图访问数组

array

的第

11

个元素(索引为

10

),但是

array

实际上只有

10

个元素(索引从

0

9

)。这是一个典型的数组越界访问错误。

使用cppcheck静态代码扫描工具进行扫描,会得到类似以下的扫描结果:
在这里插入图片描述
结果清晰命令:

[example.c:11]: (error) Array 'array[10]' accessed at index 10, which is out of bounds.

,翻译过来就是:

example.c的11行存在错误:数组array试图访问下标为10的数组元素,这超出了数组的边界

根据扫描结果的提示,我们应该修复数组越界访问的问题。修复方案如下:

  1. 确保数组索引在有效范围内。
  2. 如果需要访问数组的最后一个元素,使用sizeof(array) / sizeof(array[0]) - 1来计算最后一个有效索引。

问题2:变量未初始化val

exampleFunction1

这个函数声明了一个整数变量

value

,但没有初始化它。然后它检查

value

是否等于 0,但由于

value

是未初始化的,这个检查是未定义的,因为它可能包含任何随机值,也就是每次运行可能会进入if分支,也可能会引入else分支,完全是一个随机事件。

使用cppcheck静态代码扫描工具进行扫描,会得到类似以下的扫描结果:
在这里插入图片描述
结果清晰命令:

[example.c:24]: (error) Uninitialized variable: value

,翻译过来就是:

example.c的24行存在错误:未初始化变量:value

根据扫描结果的提示,我们应该修复变量未初始化的问题。修复方案如下:

  1. 在定义所有变量时,确保对其进行初始化。

问题3:申请的内存未释放

exampleFunction2

这个函数分配了

10

字节的内存给

buffer

,然后尝试将字符串

"haha"

(包括一个终止符 ‘\0’ 总共 5 个字符)复制到

buffer

中。函数在退出前没有释放分配的内存,导致出现了内存泄漏。

使用cppcheck静态代码扫描工具进行扫描,会得到类似以下的扫描结果:
在这里插入图片描述
结果清晰命令:

[example.c:46]: (error) Memory leak: buffer

,翻译过来就是:

example.c的46行存在错误:内存泄漏:value

根据扫描结果的提示,我们应该修复变量未初始化的问题。修复方案如下:

  1. 确保在不再需要内存时使用free函数释放它。

修复后的代码

#include<stdio.h>#include<stdlib.h>#include<string.h>intexampleFunction(){printf("%s enter\n",__func__);int array[10];int index =sizeof(array)/sizeof(array[0])-1;
    array[index]=42;// 数组越界访问,已经修复printf("%s leave\n",__func__);return0;}intexampleFunction1(){int value =0;// 变量未初始化,已经修复printf("%s enter\n",__func__);if(value ==0){printf("value is 0");}else{printf("value not 0");}printf("%s leave\n",__func__);return0;}intexampleFunction2(){char*buffer =NULL;printf("%s enter\n",__func__);

    buffer =malloc(10);//buffer申请的内存没有释放,已经修复strcpy(buffer,"haha");free(buffer);printf("%s leave\n",__func__);return0;}intmain(int argc,char*argv[]){exampleFunction();exampleFunction1();exampleFunction2();return0;}

修复后的代码,编译运行结果如下所示,可以看到,所有函数正常执行,使用

valgrind

检测,也没有内存泄漏了。
在这里插入图片描述

结论

CppCheck 是一款强大的静态代码分析工具,可以大幅提升C/C++代码的质量和安全性。通过安装和使用CppCheck,可以提前发现潜在的问题,减少Bug和漏洞的产生。同时,将CppCheck集成到CI/CD管道中,可以实现持续化代码检测,确保代码库始终保持高质量。希望本文对你了解和使用CppCheck有所帮助,让你的代码更加安全可靠。如果有任何疑问或需要进一步讨论,欢迎在评论区留言!


本文转载自: https://blog.csdn.net/g310773517/article/details/140320629
版权归原作者 I'mAlex 所有, 如有侵权,请联系我们删除。

“【工具推荐】CppCheck:C/C++静态代码检测工具的使用教程和实战案例,提前发现隐患,让你的代码更安全”的评论:

还没有评论