Valgrind

目录

valgrind简介

memcheck 检测内存问题的原理

memcheck检测原理

valgrind安装流程

常见的内存问题

使用了未初始化的内存

内存读写越界

动态内存管理错误


valgrind简介

valgrind 是一个提供了一些 debug 和优化的工具的工具箱,可以使得你的程序减少内存泄漏或者错误访问,valgrind 默认使用 memcheck 去检查内存问题.

memcheck 检测内存问题的原理

Memcheck 能够检测出内存问题,关键在于其建立了两个全局表。

  1. valid-value map:
    对于进程的整个地址空间中的每一个字节(byte),都有与之对应的 8 个 bits;对于 CPU 的每个寄存器,也有一个与之对应的 bit 向量。这些 bits 负责记录该字节或者寄存器值是否具有有效的、已初始化的值
  2. valid-address map
    对于进程整个地址空间中的每一个字节(byte),还有与之对应的 1 个 bit,负责记录该地址是否能够被读写

memcheck检测原理

  • 当要读写内存中某个字节时,首先检查 valid-address map 中这个字节对应的 A bit。如果该A bit显示该位置是无效位置,memcheck 则报告读写错误。
  • 内核(core)类似于一个虚拟的 CPU 环境,这样当内存中的某个字节被加载到真实的 CPU 中时,该字节对应的 V bit (在 valid-value map 中) 也被加载到虚拟的 CPU 环境中。一旦寄存器中的值,被用来产生内存地址,或者该值能够影响程序输出,则 memcheck 会检查对应的 V bits,如果该值尚未初始化,则会报告使用未初始化内存错误。

valgrind安装流程

 sudo apt-get install valgrind

删除所有日志:

rm valgrind.log.*

 在命令memcheck下,启动:

G_SLICE=always-malloc G_DEBUG=gc-friendly  valgrind -v --tool=memcheck --leak-check=full --num-callers=40 --log-file=valgrind.log <program> <arguments>

查看帮助文档:

valgrind --help

 使用valgrind带有的memcheck工具检查内存泄漏情况:

Memcheck是一个内存错误检测器。它可以检测C和c++程序中常见的下列问题。

访问你不应该访问的内存,例如溢出或欠运行堆块,溢出堆栈顶部,以及在释放内存后访问内存。

使用未定义的值,即未初始化的值,或从其他未定义的值派生的值。

不正确地释放堆内存,例如双重释放堆块,或者不匹配地使用malloc/new/new[]与free/delete/delete[]

memcpy和相关函数中的src和dst指针重叠。

内存泄漏。

valgrind --tool=[memcheck]

报错:valgrind: failed to start tool '[memcheck]' for platform 'arm-linux': No such file or directory 

解决:我的ubuntu系统是32位,valgrint是64位的

char    *p;
printf("%d\n",sizeof(p));

使用以下命令执行程序:

G_SLICE=always-malloc G_DEBUG=gc-friendly  valgrind -v --tool=memcheck --leak-check=full --num-callers=40 --log-file=valgrind.log <program> <arguments>

执行异常结束,出现了Killed字样

查看valgrind日志

cat valgrind.log

就可以知道出错的情况了

常见的内存问题

【参考自valgrind 的使用 - 简书 (jianshu.com)

使用了未初始化的内存

内存读写越界

动态内存管理错误

  • 申请和释放不一致
    由于 C++ 兼容 C,而 C 与 C++ 的内存申请和释放函数是不同的,因此在 C++ 程序中,就有两套动态内存管理函数。一条不变的规则就是采用 C 方式申请的内存就用 C 方式释放;用 C++ 方式申请的内存,用 C++ 方式释放。也就是用 malloc/alloc/realloc 方式申请的内存,用 free 释放;用 new 方式申请的内存用 delete 释放。在上述程序中,用 malloc 方式申请了内存却用 delete 来释放,虽然这在很多情况下不会有问题,但这绝对是潜在的问题。
  • 申请和释放不匹配
    申请了多少内存,在使用完成后就要释放多少。如果没有释放,或者少释放了就是内存泄露;多释放了也会产生问题。
  • 释放后仍然读写
    本质上说,系统会在堆上维护一个动态内存链表,如果被释放,就意味着该块内存可以继续被分配给其他部分,如果内存被释放后再访问,就可能覆盖其他部分的信息,这是一种严重的错误。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值