代码检查工具文档.docx
- 文档编号:5873349
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:18
- 大小:882.72KB
代码检查工具文档.docx
《代码检查工具文档.docx》由会员分享,可在线阅读,更多相关《代码检查工具文档.docx(18页珍藏版)》请在冰豆网上搜索。
代码检查工具文档
代码检查工具
一.内存泄漏的发生方式
1).常发性
2).偶发性
3).一次性
4).隐式
二.代码检查的方式
代码检查的方式分为静态代码检查(Staticprogramanalysis)和动态代码检查(Dynamicprogramanalysis)。
三.动态代码检查——Valgrind简单用法
1).valgrind包含的工具
①.memcheck最常用的工具,也是valgrind默认的工具。
用来检测程序中出现的内存问题,所有对内存的读写都会被检测到。
一切对malloc()/free()、new/delete的调用都会被捕获,所以它能检测以下问题:
Ø对未初始化内存的使用
Ø读/写释放后的内存块
Ø读/写超出malloc分配的内存块
Ø读/写不适当的栈中内存块
Ø内存泄漏,指向一块内存的指针永远丢失
Ø不正确的malloc/free或new/delete匹配
ØMemcpy()相关函数中的dst和src指针重叠。
②.callgrind,它不需要在编译源码时附加特殊选项,但推荐加上调试选项,callgrind搜集程序运行时的一些数据,建立函数调用关系图,还可以有选择的进行cache模拟,在运行结束时,它会把分析数据写入一个文件。
简而言之,它主要用来检查程序中函数调用过程中出现的问题。
③.cachegrind,它模拟CPU中的一级缓存和二级缓存,能够精确的指出程序中cache的丢失和命中。
如果需要,它还能为我们提供cache丢失的次数,内存引用次数,以及每行代码、每个函数、每个模块、整个程序产生的指令数。
对优化程序有很大帮助。
④.helgrind,它主要用来检查多线程程序中出现的竞争问题。
Helgrind寻找内存中被多个线程访问而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方。
而且会导致难以发掘的错误。
⑤.massif,堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块、堆管理块和栈的大小。
它能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能加速我们的程序运行,减少程序停留在交换区中的几率。
⑥.extension。
可以利用core提供的功能,自己编写特定的内存调试工具。
2).valgrind的使用
Valgrind[valgrind-options]your-prog[your-prog-options]
选项
作用
-h/--help
显示帮助信息
-version
显示valgrind内核版本
-q/--quiet
安静的运行,只打印错误信息
-v/--verbose
打印更详细的信息
--tool=[default:
memcheck]
运行valgrind中的工具,默认memcheck.
--leak-check=no|summary|full
要求对leak列出详细信息[default:
summary]
--log-file=
Path+日志信息文件
3).使用示例
①.未释放内存,数组越界.sample.c
#include
voidfun()
{
int*p=(int*)malloc(10*sizeof(int));
p[10]=0;
}
intmain(intargc,char*argv[])
{
fun();
return0;
}
1.编译:
gcc–gsample.c–osample
2.使用valgrind:
valgrind--leak-check=full./sample
输出信心分析如下图所示:
示例程序中有两个问题,一是fun()函数中动态申请的堆内存没有释放。
二是对堆内存的访问越界。
②.使用未初始化的内存。
badloop.c
#include
intmain(void)
{
inta[5];
inti,s;
a[0]=a[1]=a[2]=a[3]=a[4]=0;
for(i=0;i<5;i++)
s+=a[i];
if(s==168)
printf("sumis%d\n",s);
return0;
}
1.编译:
gcc–gbadloop.c–obadloop
2.使用valgrind:
valgrind--leak-check=full./badloop
输出信心分析如下图所示:
③.内存读写越界。
badacc.c
#include
#include
intmain(void)
{
intlen=4,i;
int*pt=(int*)malloc(len*sizeof(int));
int*p=pt;
for(i=0;i { p++; } *p=5; printf("thevalueofpequal: %d\n",*p); return0; } 1.编译: gcc–gbadacc.c–obadacc 2.使用valgrind: valgrind--leak-check=full./badacc 输出信心分析如下图所示: ④.内存覆盖。 badlap.cpp #include #include #include intmain(intargc,char*argv[]) { charx[50]; inti; for(i=0;i<50;i++) { x[i]=i+1; } strncpy(x+20,x,20); strncpy(x+20,x,21); strncpy(x,x+20,20); strncpy(x,x+20,21); x[39]='\0'; strcpy(x,x+20); x[39]=39; x[40]='\0'; strcpy(x,x+20); return0; } 1.编译: g++–gbadlap.c–obadlap 2.使用valgrind--leak-check=full./badlap 输出信心分析如下图所示: 代码画红线部分地址相差20,但是拷贝长度却是21,这样就会覆盖之前的值。 Valgrind也很精确的检测出了这一点。 ⑤.动态内存管理错误。 badmac.cpp 常见的内存动态管理错误: ●申请和释放不一致(malloc/alloc/realloc申请用free。 new用delete) ●申请和释放不匹配,申请了多少内存,在使用完成后就要释放多少。 如果没有释放或者少释放了就是内存泄漏,多释放了也会产生问题。 ●释放后仍然读写。 #include #include intmain(intargc,char*argv[]) { inti; char*p=(char*)malloc(10); char*pt=p; for(i=0;i<10;i++) { p[i]=65+i; } deletep; pt[1]='x'; free(pt); return0; } 1.编译: g++–gbadmac.c–obadmac 2.使用valgrind--leak-check=full./badmac 输出信心分析如下图所示: 由图可以看出,valgrind准确定位出这三个错误。 ⑥.内存泄漏 内存泄漏(Memoryleak)指的是在程序中动态申请的内存,使用完成后即没有释放,又无法被程序的其它部分访问。 Tree.h #ifndef__BADLEAK__ #define__BADLEAK__ typedefstruct__node{ struct__node*l; struct__node*r; charv; }node; node*mk(node*l,node*r,charval); voidnodefr(node*n); #endif Tree.cpp #include #include"tree.h" node*mk(node*l,node*r,charval) { node*f=(node*)malloc(sizeof(node)); f->l=l; f->r=r; f->v=val; returnf; } voidnodefr(node*n) { if(n) { nodefr(n->l); nodefr(n->r); free(n); } } Badleak.cpp #include #include"tree.h" intmain(intargc,char*argv[]) { node*tree1,*tree2,*tree3; printf("test\n"); tree1=mk(mk(mk(0,0,'3'),0,'2'),0,'1'); tree2=mk(0,mk(0,mk(0,0,'6'),'5'),'4'); tree3=mk(mk(tree1,tree2,'8'),0,'7'); return0; } Makefile badleak: badleak.otree.o g++-obadleakbadleak.otree.o badleak.o: badleak.cpp g++-g-cbadleak.cpp tree.o: tree.cpp g++-g-ctree.cpp clean: rm-rf*.o rm-rfbadleak 至此,valgrind常用的方法已总结完毕,置于valgrind的其它工具使用在此就不一一列举。 四.静态代码检查Splint 静态程序分析(staticprogramanalysis): 静态程序分析是指使用自动化工具软件对程序源代码进行检查,以分析程序行为的技术,应用程序的正确性、安全缺陷检测、程序优化等。 它的特点是不执行程序。 1.Splint的检测范围: ✓可能的空指针 ✓在释放内存之后使用了该指针 ✓赋值次序问题 ✓拼写错误 ✓被零除 ✓失败的case语句(遗漏了break语句) ✓不可移植的代码 ✓宏定义参数没用圆括号 ✓符号的丢失 ✓异常的表达式 ✓变量没有初始化 ✓转换类型不一致 ✓可疑的判断语句(例如: if(x=0)) ✓Printf/scanf的格式检查 2.Splint的使用 在Linux命令行下,splint的使用很简单,检测文件*.c,用法如下: splint*.c 检查控制 splint提供了三种方式可进行检查的控制,分别是.splintrc配置文件、flags标志和格式化注释。 flags: splint支持几百个标志用来控制检查和消息报告,使用时标志前加’+‘或’-’,'+'标志开启这个标志,'-'表示关闭此标志,下面例子展示了flags标志的用法: splint-showcola.c//在检测a.c时,告警消息中列数不被打印 splint-varusea.c//在检测a.c时,告警消息中未使用变量告警不被打印 .splintrc配置文件: 在使用源码安装splint之后,.splintrc文件将被安装在主目录下,.splintrc文件中对一些标志作了默认的设定,命令行中指定的flags标志会覆盖.splintrc文件中的标志。 格式化注释: 格式化注释提供一个类型、变量或函数的格外的信息,可以控制标志设置,增加检查效果,所有格式化注释都以/*@开始,@*/结束,比如在函数参数前加/*@null@*/,表示该参数可能是NULL,做检测时,splint会加强对该参数的值的检测。 3.使用示例 ①.认识splint输出的警告消息 #include intfunc_splint_msg1(void) { inta; return0; } intfunc_splint_msg2(void) { int*a=(int*)malloc(sizeof(int)); a=NULL; return0; } 直接运行: splintsample.c ②.使用空指针null_point.c #include intfunc_null_point(void) { int*a=NULL; return*a; } 直接运行: splintnull_point.c ②.转换类型不一致问题types.c #include voidsplint_types(void) { shorta=0; longb=32768; a=b; return; } 直接运行: splinttypes.c ③.内存管理memory_managment.c #include #include //当有其他指针引用当时候,释放一块空间 voidmemory_management(void) { int*a=(int*)malloc(sizeof(int)); int*b=a; free(a); *b=0; } 直接运行: splintmemory_managment.c #include #include voidmemory_management(void) { int*a=(int*)malloc(sizeof(int)); a=NULL; } 直接运行: splintmemory_managment.c ④.缓存边界buffersize.c #include #include voidbounds1(void) { inta[10]; a[10]=0; } 直接运行: splint+boundsbuffersize.c voidbounds2(char*str) { char*tmp=getenv("HOME"); if(tmp! =NULL) { strcpy(str,tmp); } } 直接运行: splint+boundsbuffersize.c 警告指出,在使用strcpy(str,tmp)时可能出现越界错误,因为str大小未知。 五.CppcheckC/C++静态代码分析工具 这个工具可以在windows下安装。 双击 即可安装。 安装后启动界面为: Cppcheck检测的是整个目录。 单击 即可打开一个目录。 示例: sample目录下有一个sample.c代码如下: #include voidfun() { int*p=(int*)malloc(10*sizeof(int)); p[10]=0; } intmain(intargc,char*argv[]) { fun(); return0; } 检测结果: 关于cppcheck用法这里不再一一赘述。 小结: 代码检查工具有很多,通过我多方搜索,就觉得这三款还不错。 有了这些工具的帮助虽然可以提高我们程序运行的质量。 但是代码的编写还要靠各位大神的细心和耐心。 写出优质的代码,让这些检查工具无可检查。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 代码 检查 工具 文档