Valgrind简介 Valgrind是一套Linux下,开放源代码(GPLV2)的仿真调试工具的集合。 Valgrind工具包包含多个工具,如Memcheck、Cachegrind、Helgrind、Callgrind、Massif。Memcheck工具 Memcheck工具是Valgrind中最常用的工具,用来检测程序中出现的内存问题。它能检测如下问题:使用未初始化内存;使用释放后的内存;使用超出malloc分配的内存块;对堆栈的非法访问;内存泄漏;不正确的mallocfree或newdelete匹配;memcpy()相关函数中的dst和src指针重叠。Cachegrind工具 Callgrind收集程序运行时的一些数据,函数调用关系等信息,还可以有选择地进行cache模拟。在运行结束时,它会把分析数据写入一个文件。callgrindannotate可以把这个文件的内容转化成可读的形式。Helgrind工具 它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。Helgrind实现了名为Eraser的竞争检测算法,并做了进一步改进,减少了报告错误的次数。Callgrind工具 它模拟CPU中的一级缓存I1,D1和L2二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。Massif工具 堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。 Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。 Valgrind由内核(core)以及基于内核的其他调试工具组成。其基于仿真方式对程序进行调试,它先于应用程序获取实际处理器的控制权,并在实际处理器的基础上仿真一个虚拟处理器,并使应用程序运行于这个虚拟处理器之上,从而对应用程序的运行进行监视。 应用程序并不知道该处理器是虚拟的还是实际的,已经编译成二进制代码的应用程序并不用重新进行编译,Valgrind直接解释二进制代码使得应用程序基于它运行,从而能够检查内存操作时可能出现的错误。所以在Valgrind下运行的程序运行速度要慢得多,而且使用的内存要多得多。因此,最好在性能好的机器上使用Valgrind,并且是在开发调试阶段使用。Valgrind安装 Valgrind的安装方式很简单。我们首先查看一下我们的系统中有没有Valgrind: 显然,我们这里的系统中没有Valgrind,按提示输入如下命令安装即可:sudoaptinstallvalgrind 另外,也可以通过下载源码编译、安装。 源码地址: http:valgrind。org 下载源码的命令:wgethttp:valgrind。orgdownloadsvalgrind3。14。0。tar。bz2Valgrind使用 准备一个有内存泄漏、内存越界问题的demo进行测试。为了方便,我们使用官方提供的一个经典的测试demo: valgrindtest。c:includestdlib。hvoidf(void){intxmalloc(10sizeof(int));x〔10〕0;problem1:heapblockoverrun}problem2:memoryleakxnotfreedintmain(void){f();return0;} 这份代码存在两个问题:使用超出malloc分配的内存。内存泄漏。 下面一起来使用valgrind的Memcheck工具来检测这份程序。 首先,我们使用g编译程序以包含调试信息,以便Memcheck的错误消息包含确切的行号。gccgvalgrindtest。covalgrindtest 使用valgrind检测valgrindtest程序:valgrindleakcheckyes。valgrindtest 我们可以用tool参数指明使用的工具,如:toolmemcheck 如果不明确设置tool参数,则valgrind的检测工具默认使用的是Memcheck工具。leakcheckyes选项打开详细的内存泄漏检测器。 我们执行检测工具之后的结果如: 7407Memcheck,amemoryerrordetector7407Copyright(C)20022017,andGNUGPLd,byJulianSewardetal。7407UsingValgrind3。13。0andLibVEX;rerunwithhforcopyrightinfo7407Command:。valgrindtest74077407Invalidwriteofsize47407at0x108668:f(valgrindtest。c:6)7407by0x108679:main(valgrindtest。c:11)7407Address0x522d068is0bytesafterablockofsize40allocd7407at0x4C2FB0F:malloc(inusrlibvalgrindvgpreloadmemcheckamd64linux。so)7407by0x10865B:f(valgrindtest。c:5)7407by0x108679:main(valgrindtest。c:11)740774077407HEAPSUMMARY:7407inuseatexit:40bytesin1blocks7407totalheapusage:1allocs,0frees,40bytesallocated7407740740bytesin1blocksaredefinitelylostinlossrecord1of17407at0x4C2FB0F:malloc(inusrlibvalgrindvgpreloadmemcheckamd64linux。so)7407by0x10865B:f(valgrindtest。c:5)7407by0x108679:main(valgrindtest。c:11)74077407LEAKSUMMARY:7407definitelylost:40bytesin1blocks7407indirectlylost:0bytesin0blocks7407possiblylost:0bytesin0blocks7407stillreachable:0bytesin0blocks7407suppressed:0bytesin0blocks74077407Forcountsofdetectedandsuppressederrors,rerunwith:v7407ERRORSUMMARY:2errorsfrom2contexts(suppressed:0from0) 输出结果包含有很多信息,我们可以很容易查看到了关键的信息: 其中,输出信息告诉我们无效地写入了4个字节,并且提示了可能出现问题的代码行数。堆栈跟踪告诉我们调用了一次malloc申请内存,但并没有free,并且指出了在哪里分配了内存。 另外,这里的7407表示的是进程ID号。 内存泄漏有几种类型,最重要的两类是:definitelylost(明确的泄漏)possiblylost(可能的泄漏) 其中,明确的泄漏必须要进行修复。 以上就是关于valgrind最常用的Memcheck工具的简单使用介绍,使用Memcheck工具有时候我们可以很清楚地检测出程序存在的一些隐患。其它工具今后有用到的话再做分享,大家感兴趣的话可以自行去研究学习。Valgrind交叉编译 1、下载valgrind源码包:wgethttp:valgrind。orgdownloadsvalgrind3。14。0。tar。bz2 2、修改valgrind里的configure文件: 把armv7)改成armv7arm)。 3、生成Makefile。configurehostarmlinuxgnueabihfCChomeLinuxZnToolChaingccarmlinuxgnueabihf6。2。1binarmlinuxgnueabihfgccCXXhomeLinuxZnToolChaingccarmlinuxgnueabihf6。2。1binarmlinuxgnueabihfgprefixPWDtmp 这个命令似乎很长,但并不难,只是加了几个配置参数。这些配置参数怎么看? 我们可以输入。configurehelp命令来查看支持的配置: 下面我们依次来分析上面那个很长的命令:hostarmlinuxgnueabihf:表明了我们最终可执行文件运行的环境。CChomeLinuxZnToolChaingccarmlinuxgnueabihf6。2。1binarmlinuxgnueabihfgcc:这是指定我们的交叉编译工具armlinuxgnueabihfgcc,这里直接给出绝对路径。CXXhomeLinuxZnToolChaingccarmlinuxgnueabihf6。2。1binarmlinuxgnueabihfg:这是指定我们的交叉编译工具armlinuxgnueabihfg,这里直接给出绝对路径。prefixPWDtmp:指定安装的路径。表明安装路径在当前路径下的tmp文件夹中。 这时候已经生成了Makefile文件: 编译、安装:makemakeinstall 安装完成后tmp文件夹下的内容为: 这时候我们就可以把tmp整个文件夹拷到板子上使用了。tmp的大小为一百多兆,注意查看板子存储空间够不够: 我们可以配置板子上的valgrind环境。如果仅是临时使用,可以这么用:tmpbinvalgrindtoolmemcheckleakcheckyes。valgrindtest 其中,tmp文件夹与与valgrindtest在同一路径。这时候可能会报如下错误:valgrind:failedtostarttool‘memcheck’forplatform‘armlinux’:Nosuchfileordirectory 这是因为valgrind需要依赖其动态库,而没有找到动态库。因为是临时测试,在valgrindtest路径输入如下命令进行设置:exportVALGRINDLIBtmplibvalgrind 这只是在当前开发板终端生效,下次重新进入开发板终端需要重新设置。参考资料 1、https:www。valgrind。orgdocsmanualquickstart。htmlquickstart。prepare 2、https:blog。csdn。netandylaurenarticledetails93189740 3、https:zhuanlan。zhihu。comp75416381 4、https:blog。csdn。netlistener51articledetails86716497?depth1 猜你喜欢: 分享几款优秀的绘图工具 实用分享几个非常实用的开源项目 C语言、嵌入式重点知识:回调函数 嵌入式必备之Git的使用 1024G嵌入式资源大放送!包括但不限于CC、单片机、Linux等。私信回复1024,即可免费获取!