cppcheck的检查项的实现
C语言代码审查了解在C语言项目中进行代码审查的方法
C语言代码审查了解在C语言项目中进行代码审查的方法在C语言项目开发中,进行代码审查是一项非常重要的任务。
代码审查是通过对代码进行检查和分析,以确保代码的质量、可读性和可维护性。
本文将介绍在C语言项目中进行代码审查的方法。
一、代码审查的重要性代码审查是一种对代码进行全面检查和评估的过程,具有以下几个重要作用:1. 提高代码质量:通过代码审查,可以发现和纠正潜在的错误、缺陷和漏洞,从而提高代码的质量和稳定性。
2. 增强代码可读性:代码审查可以强制开发人员遵循编码规范,统一代码风格,提高代码的可读性和可维护性。
3. 加强团队协作:通过代码审查,可以促进团队内部的合作和沟通,减少代码冲突和错误。
二、代码审查的步骤进行代码审查时,可以按照以下步骤进行:1. 确定审查标准:制定一套适合团队的代码审查标准,包括代码风格、命名规范、注释规范等。
确保所有审查人员都明确了这些标准。
2. 预审查准备:审查人员在开始审查之前,应仔细阅读和理解要审查的代码。
了解代码的功能、结构和设计思路。
3. 代码审查:审查人员针对代码进行检查,包括但不限于以下几个方面:- 代码逻辑错误:检查代码是否有语法错误、运行时错误或逻辑错误。
- 标准合规性:检查代码是否符合事先确定的编码规范和标准。
- 可读性:检查代码的可读性,包括变量命名、注释、代码缩进等。
- 代码复用性:检查代码是否可以重用,并提出改进建议。
4. 记录问题:审查人员应记录代码中存在的问题和改进建议,并标记在代码中或记录在审查文档中。
5. 各方讨论:审查人员将审查结果和改进建议与代码作者进行讨论,共同解决问题并改进代码。
6. 进行修改:根据讨论结果,代码作者对代码进行修改以解决问题和改善代码质量。
7. 后续审查:在代码修改完成后,再次进行审查以确保问题已解决。
三、代码审查的工具为了提高代码审查的效率和准确性,可以使用一些代码审查工具。
以下是几个常用的C语言代码审查工具:1. SonarQube:一个开源的代码质量管理平台,支持C语言等多种编程语言。
cppcheck检查规则
R-2-8-2
每个指定的抛出必须有与之匹配的捕获。
R-2-8-3
异常抛出的对象必须使用引用方式捕获。
R-2-8-4
缺省捕获必须放在所有指定捕获之后。
R-2-8-5
禁止显式直接抛出NULL。
规则
中文描述
R-1-2-3
禁止在头文件前有可执行代码。
R-1-2-4
引起二义性理解的逻辑表达式,必须使用括号显式说明优先级顺序。
R-1-2-5
逻辑判1-3-3
禁止对参数指针进行赋值。
R-1-3-7
动态分配的指针变量定义时如未被分配空间必须初始化为NULL
R-1-3-8
A-1-6-3
动态申请的内存空间用完后及时释放。
A-1-11-1
建议变量在声明的同时进行初始化。
R-2-7-1
函数中固定长度数组变量的传递必须使用引用方式。
R-2-7-2
定义为const的成员函数禁止返回非const的指针或引用。
R-2-7-3
禁止可导致非资源性对象数据被外部修改的成员函数返回。
R-2-8-1
动态分配的指针变量第一次使用前必须进行是否为NULL的判别。
R-1-6-8
数组禁止越界使用。
R-1-6-9
数组下标必须是大于等于零的整型数。
R-1-6-16
禁止使用已被释放了的内存空间。
R-1-6-17
被free的指针必须指向最初malloc、calloc分配的地址。
A-1-1-6
建议用宏或const定义常数。
C语言中的安全测试与漏洞扫描工具
C语言中的安全测试与漏洞扫描工具随着信息技术的发展和应用,软件安全性日益成为人们关注的焦点。
在软件开发和维护过程中,安全测试是保障软件安全性的重要环节之一。
而在C语言中,安全测试和漏洞扫描工具的使用能够帮助开发人员及时发现和修复潜在的安全漏洞,从而提高软件的安全性。
一、安全测试的重要性在C语言中进行安全测试的重要性不容忽视。
C语言是一种广泛应用的编程语言,其灵活的特性使得在编程过程中容易引入一些安全隐患,如缓冲区溢出、空指针引用等。
这些安全漏洞容易被黑客利用,造成严重的安全问题,如信息泄露、拒绝服务等。
因此,通过安全测试及时发现这些问题,对软件的安全性具有重要意义。
二、常见的C语言安全测试工具1. CppcheckCppcheck是一款开源的静态代码分析工具,主要用于检查C/C++代码中的错误和潜在的安全漏洞。
它能够检测出常见的错误,如空指针引用、内存泄漏、整数溢出等,并给出相应的建议。
使用Cppcheck进行安全测试,可以大大减少开发人员在安全问题上的盲点。
2. ValgrindValgrind是一款强大的内存调试和性能分析工具,也可以用于C语言的安全测试。
通过Valgrind,开发人员可以检测出内存泄漏、使用未初始化的变量等内存错误,并找到相应的错误位置。
此外,Valgrind 还提供了插件机制,可以根据需要进行扩展,增强工具的功能。
3. FlawfinderFlawfinder是一款简单易用的源代码安全漏洞扫描工具,主要用于检测C/C++代码中的安全问题。
它通过扫描源代码中的函数调用和代码路径,识别出潜在的安全漏洞,并给出相应的警告信息。
Flawfinder 可以帮助开发人员快速发现潜在的安全问题,提高软件的安全性。
4. Clang Static AnalyzerClang Static Analyzer是一款基于LLVM的静态代码分析工具,可以用于C语言和Objective-C语言的安全测试。
cppcheck的整体架构
……
virtual void runChecks(****){ } //实现 virtual void runSimplifiedChecks(***) = 0; //实现
添加检查函数方法: 添加检查函数方法:
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) { CheckOther checkOther(tokenizer, settings, errorLogger); // Coding style checks checkOther.warningOldStylePointerCast(); checkOther.checkUnsignedDivision(); checkOther.addcheck(); … }
字符交互模式 CmdLineParser parser(&_settings);
Cppcheck总过程 Cppcheck总过程
预处理
预处理处理由Preprocessor类实现
执行Class Preprocessor::preprocess()
预处理阶段主要处理: 去多余空格 删除汇编代码 处理#Include及嵌套 统一预处理语句(例:#if define=> #ifdef) 提取预处理配置设置(configuration) 替换宏定义
怎样加入检查类链表?
Cppcheck核心类 Cppcheck核心类check
Class check protected: const std::string _name; const Tokenizer * const _tokenizer; const Settings * const _settings; ErrorLogger * const _errorLogger; virtual void runChecks(****){ } //不是所有check子类都会实现 virtual void runSimplifiedChecks(***) = 0; //所有check子类都会实现 void reportError() //报告误差,所有check子类都会用到 virtual void getErrorMessages(****) = 0; //所有check子类都会实现,最终都会 调用reportError()
基于区间集的Cppcheck数组边界缺陷检测
De t e c t i o n o f a r r a y bo u nd o ve r lo f w b y i n t e r v a l s e t b a s e d o n Cpp c he c k
Z HA N G S h i j i n .S H A N G Z h a o w e i
J o u r n a l o f Co mp u t e r Ap p l i c a t i o n s
I S S N 1 0 0 1 . 9 0 8 1
201 3.1 1 一 O1
计算机应 用, 2 0 1 3 , 3 3 ( 1 1 ) : 3 2 5 7— 3 2 6 1
Ab s t r a c t :T h e f a l s e p o s i t i v e r a t e a n d t h e f a l s e n e g a t i v e r a t e a r e t o o h i g h f o r t h e o p e n s o u r c e s o f t wa r e C p p c h e c k ,a n d d e f e c t s c a n n o t b e d e t e c t e d d u in r g p r o g r a m r u n n i n g .I n t e r v a l s e t a l g o i r t h m w a s p u t f o r w a r d o n t h e b a s i s o f Cp p c h e e k p r o ra g m a n d w a s u s e d f o r d e t e c t i n g a r r a y b o u n d o v e r f l o w.S h a p i n g i n t e va r l s e t a n d a r r a y i n t e r v a l s e t we r e e s t a b l i s h e d b y i n t r o d u c i n g t h e c o n c e p t o f i n t e va r l s e t .E a c h p r o ra g m v a ia r b l e s a n d e x p r e s s i o n s i n t e va r l v lu a e s we r e c o n s t r u c t e d u n d e r t h e f r a me w o r k o f C p p c h e c k t o d e t e c t c o n t r a d i c t i o n s t o l o c a t e d e f e c t s .T h e p r e c i s i o n r a t e i n c r e a s e d b y 1 8 . 5 % .t h e f a l s e n e g a t i v e r a t e d e c r e a s e d b y 2 2 . 5 % a n d t h e f a l s e p o s i t i v e r a t e i n c r e a s e d b y 3 . 5 % w i t h t h e a l g o r i t h m c o mp a r e d t o C p p c h e e k .T h e e x p e i r me n t a l r e s u l t s s h o w t h a t t h e p r o p o s e d lg a o r i t h m c a n e f f e c t i v e l y d e t e c t t h e d e f e c t s o f r u n n i n g p r o ra g m a n d t h e d e t e c t i o n p e f r o r ma n c e g e t s
cppcheck源码学习
cppcheck源码学习Cppcheck是一个非常强大的开源C/C++静态代码分析工具,可以帮助开发者发现代码中的各种潜在问题和错误。
本文将介绍Cppcheck的一些基本原理和主要功能,并通过分析Cppcheck源码,帮助读者深入了解Cppcheck的实现细节和工作原理。
Cppcheck使用C++语言编写,源码可以从Github上获取。
Cppcheck 的主要入口是cppcheck.cpp文件,该文件定义了Cppcheck类,并包含了Cppcheck的主要逻辑。
Cppcheck类是Cppcheck的核心类,负责整个工具的控制流程和数据处理。
Cppcheck的主要工作过程可以简单地分为以下几个步骤:1. 解析源代码:Cppcheck首先通过调用Parser类,解析输入的C/C++源文件,构建抽象语法树(AST)。
2. 对AST进行遍历:Cppcheck通过调用ASTVisitor类对AST进行遍历,可以访问和处理AST中的各种节点,比如函数、变量、语句等。
3. 检查语义错误:Cppcheck通过调用各个规则类,对AST中的节点进行语义检查。
规则类是Cppcheck中定义具体规则的地方,每个规则类都会继承自Rule类,并实现了一系列方法来进行具体的规则检查。
4. 保存错误信息:在检查过程中,如果发现了错误,Cppcheck会将错误信息保存在ErrorLogger类中,以便后续的输出和展示。
5. 输出结果:最后,Cppcheck会将错误信息输出到屏幕、文件等,供开发者查看和修复代码。
在Cppcheck源码中,Parser类负责解析源代码文件,将代码生成抽象语法树。
Cppcheck通过遍历ASTVisitor类来对AST进行遍历,可以访问和处理各种节点。
通过继承ASTVisitor类,可以轻松实现对AST中节点的访问和处理。
规则类是Cppcheck中定义具体规则的地方,每个规则类都继承自Rule类,并实现了一系列用于规则检查的方法。
cppcheck软件管理制度
cppcheck软件管理制度cppcheck是一个开源的C/C++代码静态分析工具,用于检查C/C++代码中的错误、警告和潜在问题。
它可以帮助程序员在早期发现代码中的潜在问题,并提供修复建议,从而提高代码质量和可靠性。
cppcheck软件管理制度的建立和执行对于确保cppcheck软件的稳定性和可靠性至关重要。
2. 制度建立(1)目标确定:确定cppcheck软件管理制度的目标是保证软件开发质量、提高开发效率、降低开发成本,保障软件安全性和可靠性。
(2)制度范围:cppcheck软件管理制度涵盖软件开发、测试、发布、维护等全过程。
(3)团队组建:组建专门的软件开发团队,包括项目经理、开发人员、测试人员等角色,确保每个环节都有专人负责。
3. 制度执行(1)需求分析:在软件开发之前进行需求分析,明确软件功能和性能要求,确保软件开发的方向和目标。
(2)设计规范:制定统一的软件设计规范,包括软件架构设计、模块设计、数据结构设计等,确保软件设计合理、清晰、可维护。
(3)编码规范:制定统一的编码规范,包括命名规范、代码格式规范、注释规范等,确保代码风格统一、易读易懂。
(4)代码审查:进行代码审查,确保代码质量和规范性,提前发现潜在问题并及时修复。
(5)单元测试:进行单元测试,确保代码的功能正确性和完整性。
(6)集成测试:进行集成测试,确保各个模块之间的协作正常,整体功能达到预期要求。
(7)性能测试:进行性能测试,确保软件在各种条件下性能稳定可靠。
(8)发布上线:对已通过测试的软件进行发布上线,确保软件的安装和运行正常。
4. 制度监督(1)质量检查:定期对软件开发过程进行质量检查,发现问题及时整改。
(2)流程改进:根据软件开发过程中的问题和经验,及时对软件管理制度进行调整和改进。
(3)技术培训:定期组织软件开发人员进行技术培训,提高其专业技能和管理能力。
(4)绩效评估:定期对软件开发团队进行绩效评估,激励团队成员积极工作。
Check—强大的c语言单元测试框架Autotools的机理和解决过程
Check—强大的c语言单元测试框架Autotools的机理和解决过程Check —强大的c语言单元测试框架C 语言的单元测试框架,上WikiPedia可以查到很多。
经过一番比较之后,选定check作为c 语言的单元测试框架。
Check 最主要的优点是对于每一个测试用例的运行都fork 一个子进程,这么做的原因是因为 C 语言的独特性:其它语言如Java,Python,Ruby等,单元测试出错最多不过是抛出异常? C 语言如果指针操作错误,乱指一气,可是会coredump 的。
测试框架因此直接退出,用户是看不到任何返回的,只有郁闷的coredumpCheck 的单元测试运行在fork 的子进程中,可以避免测试框架由于coredump 而崩溃,优点显而易见但是在Debian 上安装check,示例代码竟然没有办法编译通过,陷入忙等待,显然是陷入了一个死循环。
Debian 上安装check,部署了下列文件(只列出主要文件):将示例拷贝到工作目录,运行,陷入可怕的死循环!CPU 占用100%:我们在运行autoreconf 时间使用了-v 参数,看到发生死循环是在运行aclocal 命令时。
怎么办呢?着急的用户,看这里将configure.ac 中的如下内容修改为:之后再参照README 中的说明执行就可以了:Autotools 的机理和解决过程为什么出错以及为什么这么做就OK 了呢?如果要说清楚,要了解autoconf, automake, aclocal 等,即autotools 的机理。
可以参考王胜的这个博文:《autotools系列工具—-自动生成Makefile》见附件下面是解决过程,其中饶了不少弯路在遇到这个问题时,首先想到的是生成新的configure.ac 文件,取代示例中的configure.ac 文件再执行aclocal ,不再死锁,但是也没有任何新文件生成比较新旧的configure.ac ,发现当注释掉AM_PATH_CHECK() 之后,便不再死锁AM_PATH_CHECK 是什么呢?我们从check 软件包的部署文件中,我们看到这个文件:/usr/share/aclocal/check.m4我们打开这个文件(/usr/share/aclocal/check.m4),看到其中只包含了一个宏AM_PATH_CHECK 的宏定义。
代码检查
1.为什么代码检查1.1能发现问题所谓静态代码检查就是使用一个工具检查我们写的代码是否安全和健壮,是否有隐藏的问题。
比如无意间写了这样的代码:int n = 10;char* buffer = new char[n];buffer[n] = 0;这完全是符合语法规范的,能编译通过,但是静态代码检查工具会提示此处会溢出。
也就是说,它是一个更加严格的编译器。
所以代码检查很有必要;1.2自动进行无需执行代码即可自动扫描缺陷、可以在软件开发的各个阶段随时扫描、缺陷自动划分严重程度等。
2.代码检查工具2.1C/C++1.Cppcheckcppcheck 是一个静态代码检查工具,支持c, c++ 代码;作为编译器的一种补充检查,cppcheck对产品的源代码执行严格的逻辑检查。
2.2JAVA1.FindbugsFindBugs 是一个JAVA静态分析工具,它检查类或者JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题。
2.CheckstyleCheckStyle提供了一个帮助JAVA开发人员遵守某些编码规范的工具。
它能够自动化代码规范检查过程,从而使得开发人员从这项重要,但是枯燥的任务中解脱出来。
2.3JS,JSP1.Js,Jsp代码检查器Js,Jsp代码检查器是一款开源的Js,Jsp代码样式检查工具,能够自动化代码规范检查过程, 支持检查本地代码和连接svn库检查配置库中代码;自动化程度高;3.在Crm5.7应用在Crm5.7项目中,按照局方要求,对前后台代码都做代码扫描,选用的工具是cppcheck,findbugs,还有一个代码扫描器;3.1下载地址:http://172.16.9.106:9001/svn/qmd/测试资料共享文件夹/代码扫描/30.代码扫描工具.zip下载用户名/密码:notesid/notes密码3.2使用3.2.1Cppcheck安装和使用1.登录linux主机2.解压:tar zxvf cppcheck-1.48.tar.gz3.cd cppcheck-1.484.编译:make5../cppcheck -h #看是否出来帮助提示6.扫描代码:cppcheck -j 3 --enable=all Project_Path/*说明:roject_Path/*:表示项目路径及项目下所有文件;j参数指定的是检查线程的个数,如果需要检查代码的量很大,-j参数还是很有用的;--enable指定当前指定的检查级别,可选的参数有all,style,information等7.举例说明:数组越界:int a[5]; a[5]=1;int a[5]; int n=5; a[n]=1;内存分配机制不匹配:int pA = new char(); free(pA);int pA = new char[5]; delete pA;内存泄露:char *p = (char *)malloc(100*sizeof(char));memset(p, 0, sizeof(p));扫描结果:[APIEncode.c:9]: (style) Variable 'a' is assigned a value that is never used[APIEncode.c:10]: (error) Array 'a[5]' index 5 out of bounds[APIEncode.c:30]: (error) Memory leak: p3.2.2FindBugs安装和使用1.解压缩findbug1[1].3.9.zip;2.将edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821 文件夹放到到myeclipse插件文件夹C:\Program Files (x86)\MyEclipse6.5\eclipse\plugins;3.将edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821 文件夹放到到myeclipse插件文件夹;4.重启myclipse;5.查看安装是否成功;6.举例说明:右击项目点击findbugs切换到findbugs视图下Findbugs 结果导出,在findbugs explorer下右击项目点击Findbugs->Save XML;3.2.3Jsp,js代码扫描器安装和使用3.2.3.1Eclipse插件版运行准备集成Eclipse插件版需要以下文件:把CheckCodeConsole_1.0.0.jar复制到eclipse/plugins目录中,重启eclipse,便可见菜单栏与工具栏提供了代码检查工具的打开按钮,点击便可打开检查器。
编码器检测c语言程序
编码器检测c语言程序检测C 语言程序中存在的编码器通常涉及到查找不安全的编码实践,例如缓冲区溢出、格式字符串漏洞、整数溢出等。
下面是一些可能用于检测C 语言程序中编码问题的方法:1. 静态代码分析工具:-使用静态代码分析工具,如Clang Static Analyzer、Coverity、PVS-Studio 等,来检测潜在的编码问题。
这些工具能够在编译前分析源代码,发现可能的错误和潜在的问题。
2. 编码规范检查:-使用编码规范检查工具,例如`cppcheck`,来确保代码符合安全编码标准。
这些工具可以检查代码中是否存在不安全的编码实践,比如缓冲区溢出。
3. 内存安全工具:-使用内存安全工具,如Valgrind,来检测内存泄漏、越界访问等问题。
这些工具可以在运行时检测程序的内存使用情况。
4. 代码审查:-进行代码审查,特别关注与字符串操作相关的代码,以及输入验证和过滤的代码段。
代码审查可以通过与团队成员合作,发现潜在的编码问题。
5. 输入验证:-对程序接受的所有输入进行验证和过滤,确保输入符合预期。
特别关注用户输入,以防止注入攻击等问题。
6. 整数溢出检查:-注意在程序中执行的所有算术运算,确保没有整数溢出问题。
使用安全的算法和数据类型,避免使用不安全的函数。
7. 使用安全函数:-使用安全的C 标准库函数,如`strcpy_s` 替代`strcpy`,`printf_s` 替代`printf` 等。
这些函数对于缓冲区操作提供了更多的安全性。
8. 网络安全工具:-使用网络安全工具,如Snort,来检测可能的网络攻击。
这对于防范一些常见的攻击手段是很有帮助的。
9. 阅读最佳实践文档:-阅读并遵循安全编码的最佳实践文档,例如CERT C Coding Standard,以了解常见的编码问题和最佳的解决方案。
请注意,这些方法并非穷尽所有可能,而且最好的做法是结合多种方法进行全面的检测。
此外,定期更新代码以反映最新的安全标准和最佳实践是非常重要的。
(完整word版)cppcheck扫描规则
constStatement
常量的声明
copyCtorPointerCopying
指针指向分配的内存,复制构造函数,而不是分配新的内存.
cstyleCast
c语言风格的指针铸造
deallocDealloc
回收一个分配指针
deallocuse
dealloc函数的使用
duplicateBreak
charArrayIndex
类型用作数组索引,如果该值可以超过127将会有一个缓冲区下溢
clarifyCalculation
可疑的计算;不明确计算的优先级
clarifyCondition
可疑的条件
clarifyStatement
可疑的声明
class_X_Y
信息处理,You can use —I or —-include to add handling of this code。
未赋值的变量
uninitMemberVar
在构筑函数中没有赋值成员变量
uninitStructMember
未初始化结构体成员
uninitvar
未初始化变量
unnecessaryQualification
是不必要的或是由许多编译器造成的错误
unreachableCode
执行不到的代码
unreadVariable
规则
描述
arrayIndexOutOfBounds
数组下标越界
arrayIndexThenCheck
数组越界访问
bufferAccessOutOfBounds
缓冲区访问越界
CastIntegerToAddressAtReturn
把整数返回地址
cppcheck的检查项的实现
cppcheck共有15个检查类实现了其检查功能
自动变量检查
自动变量问题
自动变量也就是局部变量,存储空间在栈 stack中,函数结束时空间被释放,如果此时变 量地址被外部空间的函数使用,将会引起错误。 自动变量暴露到外部窗口
从参数(指向地址变量指针即指向指针的指针) return 全局指针变量… 其他 ….
将所有自动变量 加入到 localvar 错误特征 “return %var% ; ” 且 %var% 在集合calvar中
.returncstr() returncstr()
描述:检查返回字符串自动地址的函数 (error) Returning pointer to auto variable 关键数据 std::set<unsigned int> localvar; 存储所有发现的自动变量 寻找目标函数——返回字符串的函数 特征 "const char *" 或 "> & %var% ("
自动变量地址返回
"return & %var% ;" %var% in vd_list
无效空间释放 "free ( %var% ) ;" isAutoVarArray %var% in vda_list
.returnPointerToLocalArray() returnPointerToLocalArray()
核心函数
check()
辅助函数
getAllocType() getDeallocationType()
Class CheckMemoryLeakInClass
检查
1 成员变量在构造函数中赋空间,析构函数中没有被释放 2 成员变量在函数(所有函数,不单单是一个函数中)中分配空间, 与释放空间函数不成匹配(malloc – free , new -delete)出现
CppCheck介绍与使用
CppCheck介绍与使⽤版权声明:本⽂为博主原创⽂章,未经博主允许不得转载。
https:///u011012932/article/details/52778149简述Cppcheck 是⼀种 C/C++ 代码缺陷静态检查⼯具。
不同于 C/C++ 编译器及很多其它分析⼯具,它不检查代码中的语法错误。
Cppcheck 只检查编译器检查不出来的 bug 类型,其⽬的是检查代码中真正的错误(即:零误报)。
| 版权声明:⼀去、⼆三⾥,未经博主允许不得转载。
介绍⽀持的代码和平台:可以检查⾮标准代码,包括不同的编译器扩展、内联汇编代码等。
Cppcheck 应该被处理最新 C++ 标准的任何 C++ 编译器所编译。
Cppcheck 应该在任何有⾜够 CPU 和内存的平台上⼯作。
要知道 Cppcheck 有限制,Cppcheck 很少在报告错误⽅⾯出错,但有很多 bug,它不能检测。
通过仔细测试软件,你会发现软件中有更多的 bug,⽽不是使⽤ Cppcheck。
但 Cppcheck 仍可以检测到在测试和评估软件时错过的⼀些bug。
开始使⽤第⼀个测试程序这⾥有⼀段简单的代码:int main(){char a[10];a[10] = 0;return 0;}123456将代码保存进 file.c ⽂件中,执⾏:cppcheck file.c1注意:执⾏此命令前,需要将 cppcheck.exe 所在路径添加⾄环境变量 PATH 中。
这时,将会从 cppcheck 中输出:Checking file.c …[file.c:4]: (error) Array ‘a[10]’ accessed at index 10, which is out of bounds.检查⽂件夹中的所有⽂件通常⼀个项⽬会有许多源⽂件,如果需要同时检查,Cppcheck 可以检查⽂件夹中的所有⽂件:cppcheck path1如果 path 是⼀个⽂件夹,cppcheck 将递归检查这个⽂件夹中的所有源⽂件。
cppcheck分析报告
Cppcheck分析报告1 Cppcheck的概述Cppcheck是一种代码缺陷静态检查工具。
不同于编译器以及其它分析工具,cppcheck只检查编译器检查不出来的bug,不检查语法错误。
Cppcheck将软件缺陷从静态源代码的角度划分为12个检查类,分别给予检测和定位,并赋予8种不同的级别,分别为none,error,warning,style,performance,portability,information,debug。
Cppcheck实现主要包括几个方面:(1)对源代码进行适当的处理和简化,便于后面的缺陷模式检测;(2)定义一种缺陷,并讲模式提取出来,并用正确的正则表达式表示出来;(3)对提取出来的缺陷模式,采用c++编程技术在源代码中搜索、检测和定位。
Cppcheck对源代码执行严格的逻辑检查。
执行的检查包括:(1)自动变量检查;(2)数组的边界检查;(3)Class类型的检查;(4)过期的函数,废弃的函数调用检查;(5)异常的内存使用,释放检查;(6)内存泄漏检查,主要是通过内存引用指针;(7)操作系统资源释放检查,中断,文件描述符等;(8)异常STL函数检查;(9)代码格式错误以及性能因素检查。
2 Cppcheck系统分析2.1 文件处理cppcheck首先通过命令行读入带检测工程的路径,然后运用遍历文件夹的算法,遍历所有文件夹下面的cpp/c文件,每遍历一个cpp/c文件,对读取的文件进行预处理,去除注释语句,然后对预处理后的程序进行判断,对处理后的程序进行词法分析,简历Token双链表,并对Token链表进行语义分析,最后通过循环调用check子类中定义的缺陷模式,来实现缺陷的检测,最后通过errorLogger定位出程序中存在的缺陷,从而可以标记出软件中存在的相似缺陷,实现软件缺陷自动检测。
上图为文件处理流程。
2.2 Cppcheck框架Cppcheck通过8个类来实现对缺陷的检测,类名分别为:CmdLineParser、Settings、Preprocessor、Token、Tokenizer、SymbolDatabase、Cppcheck、ErrorLogger。
MALLOC_CHECK_的使用
使用环境变量MALLOC_CHECK_检查内存问题GNU C Library 可以根据环境变量MALLOC_CHECK_来决定是否在运行时可检测程序中的内存问题。
而内存问题有时候表现得非常古怪,比如random crash, crash的点又经常变,甚至coredump中也没什么栈信息。
这时候可以用这个方法来验证一下。
知识还没办法打印出错点对应的地址,有些遗憾。
下面是一个内存越界的例子:#include<stdio.h>#include<stdlib.h>#include<string.h>#define BUF_SIZE 32int main(){char* buf1 =(char*)malloc(BUF_SIZE);printf("buf1: [%x]\n", buf1);memset(buf1,'c', BUF_SIZE + 10);free(buf1);char* buf =(char*)malloc(BUF_SIZE);printf("buf: [%x]\n", buf);for(int i = 0; i < BUF_SIZE; i++){printf("%2x ",(0xFF & buf[i]));}free(buf);printf("\n");return 0;}运行结果:$ g++ test.cpp -o testmalloc: using debugging hooksmalloc: using debugging hooksmalloc: using debugging hooksmalloc: using debugging hooksmalloc: using debugging hooksmalloc: using debugging hooks$ ./testmalloc: using debugging hooksbuf1: [9b7f050]free(): invalid pointer 0x9b7f050!malloc: top chunk is corruptbuf: [9ba0008]0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0$ export MALLOC_CHECK_=2$ ./testbuf1: [a01d050]Aborted$ export MALLOC_CHECK_=0$ ./testbuf1: [9e12050]buf: [9e33008]0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0$ unset MALLOC_CHECK_$ ./testbuf1: [9062050]buf: [9062050]0 0 0 0 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63通过比较两次分配的指针地址可以看出,当使用MALLOC_CHECK_时,如果检测到memory corrupt时,有问题的memory将被特殊处理,而不是像正常情况一样被分配给新的request. 因此有可能出现使用了此环境变量之后,原本可能发生crash的程序反而工作正常了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
自动变量地址返回
"return & %var% ;" %var% in vd_list
无效空间释放 "freray %var% in vda_list
.returnPointerToLocalArray() returnPointerToLocalArray()
类检查
面向对象编程问题
c++的面向对象编程存在一些安全隐患,一些经 典 的 c++ 编 程 书 籍 都 有 提 到 , cppcheck 实 现 了 《effective c++》中提到的一些安全隐患检查 如:多态基类需要实现vitual的析构函数 不在构造和析构函数中使用vitual函数 operator = 必须返回*this operator = 需处理自我赋值的情况 …… 这些特性要加 –s 才启动
CheckMemoryLeakStructMember
检查内容:
在一个函数内、检查结构成员结构体被释放(返 回)时,其成员不释放空间
返回错误
(error) Memory leak: STRUCT.MEMBER 中间点表示成员
典型错误类型
Struct base { char *p; } Void f() { struct base *q; q=malloc(sizeof(struct base )) q->p=malloc(12); free(q); }
检查类
cppcheck共有15个检查类实现了其检查功能
自动变量检查
自动变量问题
自动变量也就是局部变量,存储空间在栈 stack中,函数结束时空间被释放,如果此时变 量地址被外部空间的函数使用,将会引起错误。 自动变量暴露到外部窗口
从参数(指向地址变量指针即指向指针的指针) return 全局指针变量… 其他 ….
存储所有发现的自动变量
寻找目标函数——返回引用的函数 寻找目标函数
函数特征 "%type% & %var% (“ 或 "> & %var% ("
.returnReference() returnReference()
提取数组特征
“[;{}] %type% %var% [” 或 “%type% < %any% > %var%”;
核心函数
check() , variable() ()
辅助函数
getAllocType() getDeallocationType()
典型错误类型
Void f() { g(malloc(SIZE)); }
其他检查
检查扩充
Cppcheck预留接口class checkother
内存泄露检查
内存泄露问题
内存泄露指的是在程序运行时,动态的申请了 内存(堆),但是使用过后没有释放,导致一些 内存永远得不到收回。 这是cppcheck最有价值的检查功能,也是实现代 码最长的一块检查
内存泄露检查
实现类
class CheckMemoryLeakStructMember class CheckMemoryLeakInFunction class CheckMemoryLeakInClass class CheckMemoryLeakNoVar
存在问题
没有处理指针传递 识别不精确 错误检查不精确
缓冲区溢出检查
缓冲区溢出问题
缓冲区也就是一块内存空间,它可以是在栈中的 局部变量(例如,静态数组),也可以是堆中的内 存区域,程序中动态产生(例如,malloc,C++支持的 动态数组)变量也就是局部变量。 所谓溢出也就是访问的地址空间超出了缓冲区内 存区域,常见有两种方式导致溢出,一是显示的 index越界,如数组越界,另外就是一些内存操作函数 使用不当引发,如memcpy,memset…等内存操作函数
CheckAutoVariables.autoVariables() CheckAutoVariables.autoVariables() 实现:
关键变量:
std::set<std::string> fp_list; 函数参数中指向指针的指针参数集合 std::set<unsigned int> vd_list; 自动变量集合 std::set<unsigned int> vda_list; 自动变量数组集合
错误捕获特征
自动变量地址被赋给函数参数
“[;{}] %var% = & %var%" %var%是fp_list . %var% in vd_list "[;{}] * %var% = & %var%" %var%是fp_list . %var% in vd_list "[;{}] %var% [ %any% ] = & %var%“ %var%是fp_list . %var% in vd_list
自动变量检查 错误举例:
由参数传递局部变量地址 由程序返回
int f(char ** fp) { Char c=’a’; *fp=&c; return 0; }
char* f(int i) { char c=‘a’; c=‘a’ return &c; }
(error) Assigning address of local (error) Return of the address of an auto-variable to a function parameter. auto-variable
类检查
实现类class CheckClass
类检查
主要实现函数
checkClass.constructors(); checkClass.operatorEq(); checkClass.privateFunctions(); checkClass.thisSubtraction(); checkClass.checkConst(); checkClass.virtualDestructor(); checkClass.operatorEqToSelf(); checkClass.operatorEqRetRefThis();
缓冲区溢出检查 错误举例:
由index越界 越界 内存操作程序使用不当
void f() { char arrary[10]; char c; c= arrary[11]; }
void f() { char* buffer=new char[10]; memset(buffer,0,11); }
缓冲区溢出检查
std::set<unsigned int> unknown_type;
bool begin_function = false; bool begin_function_decl = false 函数 进入函数的标志 进入函数参数声明部分标志
CheckAutoVariables.autoVariables() CheckAutoVariables.autoVariables()
.returncstr() returncstr()
提取变量特征 "%type% %var% [;=]" localvar.insert(tok2->next()->varId()); 将所有自动变量 加入到 localvar 错误特征
"return %var% . c_str ( ) ;“且 %var% 在集合localvar中
算法描述:
两个变量:Alloc Dealloc 一但对成员变量被分配空间,Alloc被置值,如果发现对变量 释放空间函数,Dealloc置值,并立即对比,是否是同一类内存 申请释放函数,如果不是,则立即报dismatch错,遍历完所有 类的函数
典型错误类型
class base{ private: int i; char *p; char *q; public : int j; base(); ~base(); void memalloc(); void memdealloc(); } base::base(){ p= malloc(12); } void base::memalloc(){ q = malloc(12); free(p); }
检查构造函数,析构函数中是否成对(申请,释放)(如果构造 中有内存申请,析构中必须有释放,)
(error) Memory leak: CLASSNAME ::MEMBER
Class CheckMemoryLeakInClass
实现接口(runSimplifiedChecks)
void runSimplifiedChecks(…) { … checkMemoryLeak.check(); }
错误输出
否存在有Alloc无Dealloc的情况,有则报错memleak,(有函数中有 申请,必须有函数 有函数释放,不一定在同一函数中申请释放) 有函数
(error) Memory leak: CLASSNAME ::MEMBER
发现不匹配
(error) Mismatching allocation and deallocation CLASSNAME ::MEMBER
核心函数
check()
辅助函数
getAllocType() getDeallocationType()
Class CheckMemoryLeakInClass
检查
1 成员变量在构造函数中赋空间,析构函数中没有被释放 2 成员变量在函数(所有函数,不单单是一个函数中)中分配空间, 与释放空间函数不成匹配(malloc – free , new -delete)出现
当f()运行结束时 str_local其实已经被释放了。 *好消息是 gcc就能查出此类问题