SlideShare a Scribd company logo
Cppcheck 架构分析



 自动变量检查:
 Cppcheck 概述
    返回自动变量(局部变量)指针
 越界检查:
 静态代码分析工具
  数组越界
 类检查:
   构造函数,初始化
检查点
 内存泄露检查:
 空指针检查:
 废弃函数检查
 其他:
Cppcheck 架构分析
总体
Cppcheck 系统C++实现类
参数分析

    外部输入
 class Settings
 {
   内部抽象 class Settings
   …
   std::string _append;
   std::string userDefines;
   std::list<std::string> _includePaths;
   std::list<Rule> rules;
   …
 }




    字符交互模式
      CmdLineParser parser(&_settings);
Cppcheck总过程
预处理



预处理阶段主要处理:

 去多余空格
 预处理处理由Preprocessor类
 删除汇编代码
 处理#Include及嵌套
 实现
 统一预处理语句(例:#if define=> #ifdef)
 提取预处理配置设置(configuration)
       执行Class Preprocessor::preprocess()
 替换宏定义
Tokenize




    符号:+-*/;…等
    变量名
    函数名
    解析代码成符号

  由 class Tokenizer实现
   实现接口 class Tokenizer::tokenize()
Simplify
目的:
 简化复杂代码
 统一化
由 class Tokenizer实现
实现接口 class Tokenizer::simplifyTokenList()


 Simplify规则
 对变量
 对条件循环语句if 、for、while
                       (详细规则见word)
Cppcheck 核心类class          cppcheck

 Cppcheck程序的主干类

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


 核心函数CheckFile()
  函数功能是分析一个代码文件, CheckFile()会将代码流做
 进一步的分析,做tokenize,simplify ,处理后分析代码,报告
 错误
Class cppcheck::check()函数 &class cppcheck:: CheckFile()函数的实现
Cppcheck 检查实现类check
检查类的组织方式:
          static std::list<Check *> _instances;




// Register this check class (by creating a
static instance of it)
namespace std::list<Check *> &instances()
    static
{    {
      链表在哪?
       static std::list<Check *> _instances;
  CheckOther instance;
}
          check类instances()函数中静态变量
       return _instances;
  InlineCheck::Check(const std::string &aname)
     }
       : _name(aname), _tokenizer(0),
  _settings(0), _errorLogger(0)
  :{
      怎样加入检查类链表?
       instances().push_back(this);
       instances().sort(std::less<Check *>());
  }       父类的构造函数执行时加入检查链表
Class check
 protected:
     const std::string _name;
     const Tokenizer * const _tokenizer;
     const Settings * const _settings;
     ErrorLogger * const _errorLogger;
 Cppcheck核心类check
 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
 Cppcheck 用户扩展类
 ……

 CheckOther
 virtual void runChecks(****){ }
 virtual void runSimplifiedChecks(***) = 0; //实现
                                                 //实现




  添加检查函数方法:
Thank you
检查类
cppcheck共有15个检查类实现了其检查功能
自动变量检查

自动变量问题
        自动变量也就是局部变量,存储空间
在栈stack中,函数结束时空间被释放,如果此时变
量地址被外部空间的函数使用,将会引起错误。
自动变量暴露到外部窗口
从参数(指向地址变量指针即指向指针的指针)
return
全局指针变量…
其他 ….
错误举例:
由参数传递局部变量地址                    由程序返回

int f(char ** fp)              char* f(int i)
{                              {
  Char c=’a’;                     char c=‘a’;
  *fp=&c;
   return 0;                       return &c;
自动变量检查
}                              }

(error) Assigning address of   (error) Return of the address
local auto-variable to a       of an auto-variable
function parameter.
自动变量检查
实现类 class Ch eck Au toVariables
Class CheckAutoVariables

autoVariables();
  检查自动变量
returnPointerToLocalArray();
  检查是否返回了指向局部数组的指针
returnReference()
  检查是否返货了指向局部变量的引用
returncstr()
  检查是否返回局部字符串
CheckAutoVariables.autoVariables()
实现:

关键变量:
std::set<std::string> fp_list; 函数参数中指向指针的指针参数集合
  std::set<unsigned int> vd_list; 自动变量集合
  std::set<unsigned int> vda_list; 自动变量数组集合

std::set<unsigned int> unknown_type;
bool begin_function = false;    进入函数的标志
bool begin_function_decl = false 进入函数参数声明部分标志

函数
CheckAutoVariables.autoVariables()

错误捕获特征
自动变量地址被赋给函数参数
“[;{}] %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

自动变量地址返回
  "return & %var% ;" %var% in vd_list

无效空间释放
"free ( %var% ) ;" isAutoVarArray %var% in vda_list
.returnPointerToLocalArray()
提取数组特征
 "[;{}] %type% %var% [“
      将所有数组变量加入到
  std::set<unsigned int>arrayVar
错误特征
 “return %var%” 且 %var% 在集合arrayVar中
std::string & f()
{
   std::string str_local;
返回引用函数的问题
     return   str_local;
}


 当f()运行结束时 str_local其实已经被释放了。


    *好消息是 gcc就能查出此类问题
.returnReference()
描述:检查返回自动变量引用的函数
(error) Returning reference to auto variable

关键数据
std::set<unsigned int> localvar;
存储所有发现的自动变量

寻找目标函数——返回引用的函数
函数特征 "%type% & %var% (“ 或 "> & %var% ("
.returnReference()
提取数组特征

“[;{}] %type% %var% [” 或 “%type% < %any% > %var%”;

将所有自动变量 加入到 localvar

错误特征
 “return %var% ; ” 且 %var% 在集合calvar中
.returncstr()
描述:检查返回字符串自动地址的函数

      (error) Returning pointer to auto variable

关键数据 std::set<unsigned int> localvar;
 存储所有发现的自动变量

寻找目标函数——返回字符串的函数
 特征 "const char *" 或 "> & %var% ("
.returncstr()
提取变量特征
 "%type% %var% [;=]"
  localvar.insert(tok2->next()->varId());

 将所有自动变量 加入到 localvar

错误特征
"return %var% . c_str ( ) ;“且 %var% 在集合localvar中
存在问题
没有处理指针传递
识别不精确
错误检查不精确
缓冲区溢出检查
缓冲区溢出问题

         缓冲区也就是一块内存空间,它可以是在
栈中的局部变量(例如,静态数组),也可以是堆中的
内存区域,程序中动态产生(例如,malloc,C++支持的
动态数组)变量也就是局部变量。
         所谓溢出也就是访问的地址空间超出了缓
冲区内存区域,常见有两种方式导致溢出,一是显示的
index越界,如数组越界,另外就是一些内存操作函数使
用不当引发,如memcpy,memset…等内存操作函数
错误举例:
由index越界             内存操作程序使用不当

void f()             void f()
{                    {
  char arrary[10];     char* buffer=new
  char c;            char[10];
  c= arrary[11];       memset(buffer,0,11);
缓冲区溢出检查
}                    }
缓冲区溢出检查
实现类class Ch eckBu fferO verr un
缺陷
不支持指针传递

识别缓冲区精确度不高

     动态数组,malloc固定空间等缓冲区不能识别
  字符串常量 char* p=“hello”
    (注:这段空间不是缓冲区,不可写哦)
内存操作函数检查的覆盖面不光,及一些双内存空间操作检查的不好
如memcpy(void *destin, void *source, unsigned n);
类检查
面向对象编程问题
             c++的面向对象编程存在一些安全隐患,
一 些经 典 的c++编程 书 籍都 有 提到 ,cppcheck实 现了
《effective c++》中提到的一些安全隐患检查

   如:多态基类需要实现vitual的析构函数
         不在构造和析构函数中使用vitual函数
         operator = 必须返回*this
    operator = 需处理自我赋值的情况
         ……
这些特性要加 –s 才启动
类检查
实现类class Ch eck Class
类检查
主要实现函数

 checkClass.constructors();
 checkClass.operatorEq();
 checkClass.privateFunctions();
 checkClass.thisSubtraction();
 checkClass.checkConst();
 checkClass.virtualDestructor();
 checkClass.operatorEqToSelf();
checkClass.operatorEqRetRefThis();
其他检查
检查扩充
Cppch eck预留接口 class checkother
内存泄露检查
内存泄露问题

      内存泄露指的是在程序运行时,动态的
申请了内存(堆),但是使用过后没有释放,导致一些
内存永远得不到收回。

      这是cppcheck最有价值的检查功能,也是
实现代码最长的一块检查
内存泄露检查
实现类
class CheckMemor yLeakStructMember
class CheckMemor yLeakInF unction
class CheckMemor yLeakInClass
class CheckMemor yLeakNoVar
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);
}
Class CheckMemoryLeakStructMember


  void runSimplifiedChecks(…)
实现接口(runSimplifiedChecks)
{
      CheckMemoryLeakStructMember checkMemoryLeak( …);
      checkMemoryLeak.check();
}



核心函数
 check()

 辅助函数
 getAllocType() getDeallocat ionType()
Class CheckMemoryLeakInClass
检查
Ø1 成员变量在构造函数中赋空间,析构函数中没有被释放
Ø2 成员变量在函数(所有函数,不单单是一个函数中)中分配空间,与
释放空间函数不成匹配(malloc – free , new -delete)出现

算法描述:
    两个变量: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);
}
错误输出
否存在有Alloc无Dealloc的情况,有则报错memleak,(有函数中有
申请,必须有函数释放,不一定在同一函数中申请释放)
(error) Memory leak: CLASSNAME ::MEMBER
发现不匹配
(error) Mismatching allocation and deallocation CLASSNAME ::MEMBER
检查构造函数,析构函数中是否成对(申请,释放)(如果构造
中有内存申请,析构中必须有释放,)
(error) Memory leak: CLASSNAME ::MEMBER
Class CheckMemoryLeakInClass


  void runSimplifiedChecks(…)
实现接口(runSimplifiedChecks)
{
     …
     checkMemoryLeak.check();
}



核心函数
 check() , variable()

 辅助函数
getAllocType() getDeallocationType()
Void f()
{

典型错误类型
 g(malloc(SIZE));

}
Class CheckMemoryLeakNoVar
检查

函数的参数部分有无内存泄露
报错信息:
(error) Allocation with FUNCNAME, FUNCNAME doesn't release it.
Class CheckMemoryLeakNoVar


  void runSimplifiedChecks(…)
实现接口(runSimplifiedChecks)
{
       CheckMemoryLeakNoVar checkMemoryLeak( …);
      checkMemoryLeak.check();
}



核心函数
 check()

 辅助函数
 getAllocType() getDeallocat ionType()
Class CheckMemoryLeakInFunction
检查
以函数为单位的检查,参数,局部变量指针的检查



  错误报告
Void f(char *p,int i)
{
  char *q;

典型错误
  p=malloc(10);
  q=malloc(10);

    return ;
}
Class CheckMemoryLeakInFunction


实现接口(runSimplifiedChecks)
void runSimplifiedChecks(…)
{
        CheckMemoryLeakInFunction checkMemoryLeak( …);
        checkMemoryLeak.checkReallocUsage();
        checkMemoryLeak.check();
}


核心函数
 check() parseFunctionScope() checkScope() getcode()
findLeak()

辅助函数
 getAllocType() getDeallocationType()
内存泄露新增
重写了新的函数检查类

Class CheckMemoryLeakInFunction_new

More Related Content

PPTX
Cppcheck分析
Wu Liang
 
PPT
Phpunit入门 r2
Baohua Cai
 
PPTX
Ecma script3
gniavaj
 
PPTX
检查实现类
Wu Liang
 
PDF
Testing in python 2.7.3
Wen Liao
 
DOC
Erlang jiacheng
Air-Smile
 
PPT
GTest交流与经验总结
coderzh
 
DOC
深入剖析Concurrent hashmap中的同步机制(下)
wang hongjiang
 
Cppcheck分析
Wu Liang
 
Phpunit入门 r2
Baohua Cai
 
Ecma script3
gniavaj
 
检查实现类
Wu Liang
 
Testing in python 2.7.3
Wen Liao
 
Erlang jiacheng
Air-Smile
 
GTest交流与经验总结
coderzh
 
深入剖析Concurrent hashmap中的同步机制(下)
wang hongjiang
 

What's hot (20)

PDF
Ecmascript
jay li
 
PDF
Free rtos workshop1@nuu
紀榮 陳
 
PDF
A Brief Introduction to Regular Expression with Python 2.7.3 Standard Library
Wen Liao
 
PPT
Scala function-and-closures
wang hongjiang
 
PDF
functional-scala
wang hongjiang
 
PPT
Introduction to C++ over CLI
建興 王
 
PPTX
5, workflow function activity
ted-xu
 
PDF
shell script introduction
Jie Jin
 
PPTX
認識 C++11 新標準及使用 AMP 函式庫作平行運算
建興 王
 
DOC
J2ee面试知识
yiditushe
 
DOC
深入剖析Concurrent hashmap中的同步机制(上)
wang hongjiang
 
PDF
Inside.java.concurrency 35.thread pool.part8_future.scheduledthreadpoolexecutor
Ady Liu
 
PDF
PHPUnit 入門介紹
Jace Ju
 
PPTX
前端测试
frontwindysky
 
PDF
第一次用 PHPUnit 寫測試就上手
Yi-Ming Huang
 
PPTX
5, initialization & cleanup
ted-xu
 
PPTX
PHPUnit + Xdebug 单元测试技术
hoopchina
 
PPT
改善程序设计技术的50个有效做法
crasysatan
 
PDF
潜力无限的编程语言Javascript
jay li
 
DOC
泛型总结
wang hongjiang
 
Ecmascript
jay li
 
Free rtos workshop1@nuu
紀榮 陳
 
A Brief Introduction to Regular Expression with Python 2.7.3 Standard Library
Wen Liao
 
Scala function-and-closures
wang hongjiang
 
functional-scala
wang hongjiang
 
Introduction to C++ over CLI
建興 王
 
5, workflow function activity
ted-xu
 
shell script introduction
Jie Jin
 
認識 C++11 新標準及使用 AMP 函式庫作平行運算
建興 王
 
J2ee面试知识
yiditushe
 
深入剖析Concurrent hashmap中的同步机制(上)
wang hongjiang
 
Inside.java.concurrency 35.thread pool.part8_future.scheduledthreadpoolexecutor
Ady Liu
 
PHPUnit 入門介紹
Jace Ju
 
前端测试
frontwindysky
 
第一次用 PHPUnit 寫測試就上手
Yi-Ming Huang
 
5, initialization & cleanup
ted-xu
 
PHPUnit + Xdebug 单元测试技术
hoopchina
 
改善程序设计技术的50个有效做法
crasysatan
 
潜力无限的编程语言Javascript
jay li
 
泛型总结
wang hongjiang
 
Ad

Viewers also liked (17)

PPTX
Hmaster
Wu Liang
 
PPT
Bst svn专项培训
Wu Liang
 
PPTX
函数调用关系工具-2011-孙光福
Wu Liang
 
PPTX
函数调用关系工具-Lite
Wu Liang
 
PPT
01 opening remarks
Wu Liang
 
DOCX
sarna canina
HugoM0ra
 
PPT
向量空间模型与动态规划分享
Wu Liang
 
PPTX
Dynamo cassandra
Wu Liang
 
PPTX
Trie树分享
Wu Liang
 
PPT
Smart pointer
Wu Liang
 
PPTX
An Efficient Language Model Using Double-Array Structures
Jun-ya Norimatsu
 
PDF
C++ and Software Engineering 2015
Juraj Michálek
 
PDF
Open Source Tools and the Software Engineering Process
Steve Arnold
 
PDF
COSCUP2016 - LLVM框架、由淺入淺
hydai
 
PDF
Software reliability
Baptiste Wicht
 
PPTX
Александр Куцан: "Static Code Analysis in C++"
Anna Shymchenko
 
PDF
OpenCV Introduction
Zachary Blair
 
Hmaster
Wu Liang
 
Bst svn专项培训
Wu Liang
 
函数调用关系工具-2011-孙光福
Wu Liang
 
函数调用关系工具-Lite
Wu Liang
 
01 opening remarks
Wu Liang
 
sarna canina
HugoM0ra
 
向量空间模型与动态规划分享
Wu Liang
 
Dynamo cassandra
Wu Liang
 
Trie树分享
Wu Liang
 
Smart pointer
Wu Liang
 
An Efficient Language Model Using Double-Array Structures
Jun-ya Norimatsu
 
C++ and Software Engineering 2015
Juraj Michálek
 
Open Source Tools and the Software Engineering Process
Steve Arnold
 
COSCUP2016 - LLVM框架、由淺入淺
hydai
 
Software reliability
Baptiste Wicht
 
Александр Куцан: "Static Code Analysis in C++"
Anna Shymchenko
 
OpenCV Introduction
Zachary Blair
 
Ad

Similar to cppcheck源码分析 (20)

PPTX
异步编程与浏览器执行模型
keelii
 
PPTX
Ecma script edition5-小试
lydiafly
 
PPT
千呼萬喚始出來的Java SE 7
javatwo2011
 
DOC
Java华为面试题
yiditushe
 
PDF
Efficient JavaScript Unit Testing (Chinese Version), JavaOne China 2013
Hazem Saleh
 
PPT
Sun java
softwaredesigner
 
PPTX
Dev307
建興 王
 
PDF
所谓闭包
youzitang
 
PPTX
jasmine入门指南
Zhicheng Wang
 
PPTX
[Flash开发者交流][2010.05.30]avm2虚拟机浅析与as3性能优化(陈士凯)
Shanda innovation institute
 
PPTX
Avm2虚拟机浅析与as3性能优化(陈士凯)
FLASH开发者交流会
 
PPTX
ES5 introduction
otakustay
 
PPTX
所谓闭包
ilovey4
 
PPT
第六章 函數與巨集
shademoon
 
PPT
Java Script 引擎技术
bigqiang zou
 
PDF
107个常用javascript语句 oss 计算技术 - ossez info of tech
YUCHENG HU
 
PDF
JavaScript 教程
Bobby Zhou
 
PPT
Asp.net mvc 培训
lotusprince
 
PDF
twMVC#27 | C# 7.0 新功能介紹
twMVC
 
PDF
Java8 lambda
koji lin
 
异步编程与浏览器执行模型
keelii
 
Ecma script edition5-小试
lydiafly
 
千呼萬喚始出來的Java SE 7
javatwo2011
 
Java华为面试题
yiditushe
 
Efficient JavaScript Unit Testing (Chinese Version), JavaOne China 2013
Hazem Saleh
 
Dev307
建興 王
 
所谓闭包
youzitang
 
jasmine入门指南
Zhicheng Wang
 
[Flash开发者交流][2010.05.30]avm2虚拟机浅析与as3性能优化(陈士凯)
Shanda innovation institute
 
Avm2虚拟机浅析与as3性能优化(陈士凯)
FLASH开发者交流会
 
ES5 introduction
otakustay
 
所谓闭包
ilovey4
 
第六章 函數與巨集
shademoon
 
Java Script 引擎技术
bigqiang zou
 
107个常用javascript语句 oss 计算技术 - ossez info of tech
YUCHENG HU
 
JavaScript 教程
Bobby Zhou
 
Asp.net mvc 培训
lotusprince
 
twMVC#27 | C# 7.0 新功能介紹
twMVC
 
Java8 lambda
koji lin
 

Recently uploaded (20)

PPTX
一比一制作达尔豪斯大学毕业证Dal毕业证学校版本
hiusii
 
PPTX
一比一制作渥太华大学毕业证UO毕业证学校版本
powfif
 
PPTX
美国学位证书,帝国理工学院毕业证学历认证Imperial College毕业证咨询
3of9
 
PPTX
一比一制作康考迪亚大学毕业证Concordia毕业证学校版本
nulwod
 
PPTX
新西兰学位证书,加州大学圣塔芭芭拉分校毕业证学历认证UCSB毕业证购买
yw0wm7grzexpu69wx
 
PPTX
一比一制作麦吉尔大学毕业证McGill毕业证学校版本
nulwod
 
PPTX
一比一制作贝尔法斯特女王大学毕业证QUB毕业证学校版本
dozsug
 
PPTX
一比一制作南安普顿大学毕业证Soton毕业证学校版本
ciffaw
 
PPTX
一比一制作北卡罗来纳州立大学毕业证NCSU毕业证学校版本
tenqxr2ky
 
PPTX
一比一制作南卫理公会大学毕业证SSMU毕业证学校版本
g4jp77xf2
 
PPTX
一比一制作密西西比大学毕业证Ole Miss毕业证学校版本
g4jp77xf2
 
PPTX
class deco words for every class PAK 21.pptx
huiyentan1
 
PPTX
一比一制作克拉克大学毕业证Clark U毕业证学校版本
tenqxr2ky
 
PPTX
一比一制作戴尔豪斯大学毕业证Dal业证书学校版本
hiusii
 
PPTX
美国学位证书,奥本大学毕业证学历认证Auburn毕业证办
ewzt6ecilqqoketh
 
PPTX
13每每风雨过后,特别是下雨过后,人们会感到较明显的降温。故有:“一场秋雨(风)一场寒”之说。
g4jp77xf2
 
PPTX
一比一制作俄亥俄大学毕业证OU毕业证学校版本
tenqxr2ky
 
PPTX
一比一制作堪萨斯大学毕业证UKansas毕业证学校版本
tenqxr2ky
 
PPTX
英国学位证书,爱丁堡大学毕业证学历认证Edin毕业证加急办理
3of9
 
PPTX
一比一制作爱荷华大学毕业证UI毕业证学校版本
g4jp77xf2
 
一比一制作达尔豪斯大学毕业证Dal毕业证学校版本
hiusii
 
一比一制作渥太华大学毕业证UO毕业证学校版本
powfif
 
美国学位证书,帝国理工学院毕业证学历认证Imperial College毕业证咨询
3of9
 
一比一制作康考迪亚大学毕业证Concordia毕业证学校版本
nulwod
 
新西兰学位证书,加州大学圣塔芭芭拉分校毕业证学历认证UCSB毕业证购买
yw0wm7grzexpu69wx
 
一比一制作麦吉尔大学毕业证McGill毕业证学校版本
nulwod
 
一比一制作贝尔法斯特女王大学毕业证QUB毕业证学校版本
dozsug
 
一比一制作南安普顿大学毕业证Soton毕业证学校版本
ciffaw
 
一比一制作北卡罗来纳州立大学毕业证NCSU毕业证学校版本
tenqxr2ky
 
一比一制作南卫理公会大学毕业证SSMU毕业证学校版本
g4jp77xf2
 
一比一制作密西西比大学毕业证Ole Miss毕业证学校版本
g4jp77xf2
 
class deco words for every class PAK 21.pptx
huiyentan1
 
一比一制作克拉克大学毕业证Clark U毕业证学校版本
tenqxr2ky
 
一比一制作戴尔豪斯大学毕业证Dal业证书学校版本
hiusii
 
美国学位证书,奥本大学毕业证学历认证Auburn毕业证办
ewzt6ecilqqoketh
 
13每每风雨过后,特别是下雨过后,人们会感到较明显的降温。故有:“一场秋雨(风)一场寒”之说。
g4jp77xf2
 
一比一制作俄亥俄大学毕业证OU毕业证学校版本
tenqxr2ky
 
一比一制作堪萨斯大学毕业证UKansas毕业证学校版本
tenqxr2ky
 
英国学位证书,爱丁堡大学毕业证学历认证Edin毕业证加急办理
3of9
 
一比一制作爱荷华大学毕业证UI毕业证学校版本
g4jp77xf2
 

cppcheck源码分析