内存泄漏检测神器-valgrind

valgrind是如何做到内存检测

这次没有废话。
内存检测,包括:使用了还没有初始化的内存、使用了已经被释放的内存、内存访问越界、内存泄漏等。
一个Linux下的进程在内存中是什么样子呢?地址从低到高依次是:
1.代码段(.text)这段属性为只读(肯定不能随便让人家更改呀)
2.初始化过的数据段(.data)//以上两个部分是直接从elf文件解析出来拷贝得到的
3.未初始化过的数据段(.bss)(这里放的就是一些没有初始化过的全局变量一类)
4.堆区(heap)
[这里是堆区和栈区的共同增长方向]
5.栈区(stack)
咱们继续。
valgrind的结构大概是,搭建了一个虚拟的内核环境,用来模仿CPU。valgrind为进程的整个地址空间创建了两张表,一张是valid-value表,一张是valid-address表。对于valid-value表,它描述了某个地址空间的一个byte或者是CPU的某个寄存器是否具有有效的、且已经初始化过的数据。对于valid-address表,它描述了某个地址空间的一个byte是否可以被读写。
于是一个简单的检测流程就好了:当CPU想读写某个进程地址空间的byte时,首先valgrind会检测valid-address表的这个数值是否可读写。
当CPU希望加载内存时,这个内存对应的valid-value也会被加载到valgrind的虚拟内核中。当CPU希望将某个寄存器值作为地址进行地址操作时,valgrind就会检测对应的valid-value,看看是否已经初始化过了,没有初始化的话可就是产生使用未初始化内存错误。
当然valgrind实现细节非常多,咱们这里只是理解他的工作原理,点到为止。

valgrind的简单使用

使用方法非常简单,如何安装我就不说了。
上语法:

valgrind --tool=memcheck --leak-check=full --error-limit=no --num-callers=12 --log-file=/home/xxx.log ./xxxx

解释一下:
–tool=memcheck表示使用内存检测工具,一般都用这个
–leak-check=full有设置这个选项时,当被测程序结束时查找内存泄露。设置为summary,Valgrind会统计有多少内存泄露发生
–error-limit=no:如果错误太多要停止显示新的错误的选项
–num-callers=50:这个值默认是12,最高是50。表示显示多少层的堆栈,设置越高会使Valgrind运行越慢而且使用更多的内存,但是在嵌套调用层次比较高的程序中非常实用
./xxxx: 执行被测可执行文件
当你想检测某个可执行程序是否产生内存泄漏时,不需要将其重新编译一遍的,直接拿来执行即可。
OK咱们下面看看实际输出的效果:
这里引用知乎@飞翔的猪 的图片,侵删
在这里插入图片描述
可以看到中间有heap summary,里面说明了堆的内存泄漏情况。

猜你喜欢

转载自blog.csdn.net/weixin_44039270/article/details/106616318