Cppcheck代码分析

转自:https://www.cnblogs.com/ChinaHook/p/4661030.html

            https://www.cnblogs.com/ChinaHook/p/4661062.html

1、检查点

  1、自动变量检查: 返回自动变量(局部变量)指针;

   2、越界检查:数组越界返回自动变量(局部变量)指针;

   3、类检查:构造函数初始化;

   4、内存泄露检查;

   5、空指针检查;

   6、废弃函数检查;

   7、其他。

2、Cppcheck 架构分析

  2.1 总体类图

3、检查点cppcheck系统C++实现类

 

  参数分析&外部输入

  内部抽象classSetings

class Settings

{

  …

  std::string _append;

  std::string userDefines;

  std::list<std::string> _includePaths;

  std::list<Rule> rules;

  …

}

 字符交互模式
  CmdLineParser parser(&_settings);

4、Cppcheck总过程

4.1 预处理

  预处理处理由Preprocessor类实现

  执行Class Preprocessor::preprocess()

  预处理阶段主要处理:

  •    去多余空格
  •    删除汇编代码
  •    处理#Include及嵌套
  •    统一预处理语句(例:#if define=> #ifdef)
  •    提取预处理配置设置(configuration)
  •    替换宏定义

4.2 Tokenize

  解析代码成符号,由 class Tokenizer实现,实现接口 class Tokenizer::tokenize()

  • 符号:+-*/;…等;
  • 变量名;
  • 函数名。

4.3 Simplify

  目的:简化复杂代码,   统一化

  由 class Tokenizer实现,实现接口 class Tokenizer::simplifyTokenList()

  Simplify规则:对变量;对条件循环语句if 、for、while

5、Cppcheck 核心类

  核心函数check()

  处理入口,在此函数对输入代码进行初步分析处理,最后将代码传递给 CheckFile()。

  核心函数CheckFile()

  函数功能是分析一个代码文件, CheckFile()会将代码流做进一步的分析,做tokenize,simplify,处理后分析代码,报告错误。

  Class cppcheck::check()函数  &class cppcheck:: CheckFile()函数的实现

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()

Void runChecks() 

  主要是检查经过tokenize,但未经过simplify的代码流

  Void runSimplifiedChecks()

  主要是检查经过tokenize,但未经过simplify的代码流

  用户扩展接口

CheckOther : public Check

……

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();

        …
}

6、流解析

   解析函数中的可能的代码执行流, 函数实际执行中只会执行代码流中的一条流

   分析: 分支语句 if-else ,switch-case

            循环语句 while, do-while ,for

7、代码流举例

7.1 示例代码

int main(int argc,char ** argv)
{
        std::string p_str= new  std::string() ; 
        if(std::string == NULL)
        {
            return 0;  
        }
      else
        {
            delete p_str;
        }
      return 0;
}

7.2 执行代码分析

7.2.1 执行路径1

int main()
{
    string *p_str;
    p_str= new string() ;

    (p_str == NULL);
    {
       return 0; 
    }
}

7.2.2 执行路径2

int main()
{
    string *p_str;
    p_str = new string() ;

    (p_str == NULL);
    {
        delete p_str;
    }
    return 0;
}

7.2.3 保留条件信息

#conditon ( )

#conditon_contrary ( )

int main()
{
    string *p_str;
    p_str= new string() ; 

    #conditon (p_str= = NULL);
    {
         return 0; 
    }
}


int main()
{
   string *p_str;
   p_str= new string() ;

   #conditon_contrary (p_str= = NULL);
    {
       delete p_str;
    }
    return 0;
}

7.2.4 等价替换—if

  If

if(condition)
{
   …
}

 2 paths

  1->   (condition)
  2->   (condition){ …}

  If else

if(condition)
{
   …
}
else
{
   ……
}

 2 paths

  1->   (condition){ …}
  2->   (condition){ ……}

7.2.5 等价替换—switch

swtich( int_condition)
{
   case 1:
        codes_1   
   case 2:
        codes_2
   default:
        codes_DF
}

 N paths

  1->  swith (int_condition) { codes_1 codes_2 codes_DF}
  2->  switch (int_condition) { codes_2   codes_DF }
  3->  switch (int_condition) { codes_DF }

7.2.6 等价替换—while

while ( condition)
{
   codes
}

 2 paths
  1->   (condition) ;loop{  codes ;(condition) ;}
  2->  (condition) ;  //未进入循环语句

7.2.7 等价替换—do while

do
{
   codes
}
while ( condition)

 1 path
  1->   loop{  codes ;(condition) ;}

7.2.8 等价替换—for

for( initial;condition;iterate)

{
   codes;
}

 2 path

  1->   initial ; condition ;loop{  codes ; iterate; condition;}
  2->   initial ; condition ;

8、算法思想

8.1 嵌套问题

  代码嵌套关系复杂

  解决方案 ->递归算法

8.2 空间问题

  path多,而且会重复

  解决方案 -> codeblock

8.3 codeblock

  将连续执行的代码部分以代码块的方式组合。

  多条路径共用重复的代码块

  codePath<-codeBlock<-token

Codeblock 重用

9、内存泄露检查

  函数内内存泄露检查

  找出所有与内存分配相关的函数

  找出与内存分配地址相关指针(传递性)

  是否地址传递到外部空间

  路径状态判断

  内存泄露特征

  内存申请成功&&代码路径上没有释放空间&&地址没有传递到外部空间

  地址值传递到外部空间方法:

  1.函数参数(指向指针的指针参数)

  2.调用其他函数时当参数

  3.返回值

  4.类成员变量

  5.全局变量

10、其他检查流程

10.1 其他解析

  危险使用

  使用指针前没有判断指针的值是否为空

  重复释放

  申请释放函数不一致

  malloc-free 

  new-delete

  new[]-delete[]

  ……

10.2 内存解析算法

10.2.1 pointerSet存放分配内存地址的指针

  发生指针传递时加入新集合成员

  指针被重新赋值时从集合中删除

10.2.2 检查集合中的指针

  1.当做函数的参数使用

  2.当做返回值

  3.赋值给(指向指针的参数)

10.2.2 路径上的内存状态

  UNSURE     申请内存结果未知

  NULL       申请内存失败

  OK           申请内存成功

  DEALLOCATE   内存被释放

  PASSOUT    内存地址被传递到其他窗口

10.3 条件判断解析

10.3.1 解析#condition(……

  OK NULL UNSURE NEVER

  条件语句中常见逻辑符号&& || 及小括号()

  ((ptr>0)&&other&&other)  => OK

  ((ptr>0)&&other||other)  => UNSURE

  ((ptr>0)&&(other||other)) => OK

  从左到右,深度遍历

10.3.2 条件判断解析算法

  OK NULL UNSURE NEVER

  (any)  &&  UNSURE = any

  (any)   ||   UNSURE = UNSURE

  (any)  &&  NEVER = NEVER

  (any)   || NEVER = any

  OK  &&  NULL = NEVER

  OK  ||  NULL = UNSURE

  ( A && B || C )

  ptr is a pointer in pointerSet

  (ptr)                  OK

  (|ptr)                 NULL

  (0 < ptr) (ptr > 0)        OK

  (0 != ptr) (ptr != 0)       OK

  (0 == ptr )              NULL

   other                 UNSURE

  If(A && B|| C )

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cppcheck 是一个开源的静态代码分析工具,用于检查 C/C++ 代码中的各种错误和潜在问题。它可以帮助开发者在编译之前发现并纠正代码中的常见错误,以提高代码质量和可靠性。 下面是 Cppcheck 的一些主要特点和功能: 1. 静态代码分析Cppcheck 使用静态分析技术来检查代码,而无需实际运行程序。它会对代码进行语法分析、数据流分析和控制流分析,以发现潜在的问题。 2. 错误检查:Cppcheck 可以检测出诸如空指针解引用、内存泄漏、不正确的类型转换、未初始化的变量、数组越界访问等常见错误。 3. 代码风格检查:除了错误检查外,Cppcheck 还可以帮助开发者遵循一致的代码风格和最佳实践。它可以检查缩进、命名约定、注释等方面的风格问题,并提供相应的建议。 4. 多平台支持:Cppcheck 可以在多个平台上运行,包括 Windows、Linux 和 macOS。它支持对 C 和 C++ 代码分析,并与各种开发环境和构建系统集成。 5. 定制化配置:Cppcheck 提供了丰富的配置选项,可以根据项目的具体需求进行定制。开发者可以选择要检查的错误类型、排除特定文件或目录,以及设置警告级别等。 6. 命令行和图形界面:Cppcheck 提供了命令行界面和图形界面两种使用方式。命令行界面适合集成到自动化构建过程中,而图形界面则提供了更直观的交互方式。 总之,Cppcheck 是一个强大的静态代码分析工具,可以帮助开发者发现和修复 C/C++ 代码中的各种错误和问题。它对于提高代码质量、减少潜在的漏洞和提升软件可靠性非常有价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值