使用valgrind检测ATS插件中的内存泄露
一.内存错误出现的场景
这几天在重构ATS插件代码的过程中遇到了烦人的内存泄露问题, 周五周六连续两天通过走查代码的方法,未能看出明显的导致内存错误的代码, 同时也觉得C和C++混合编程得到一个动态库, 在一个.cpp主文件中,即用new又用malloc来动态分配内存, 可能会导致内存错误.后来网上调研和查资料发现, new和malloc混用还是允许的,因为C++兼容C.虽然这种混用方式不提倡, 但绝对不会导致内存堆栈错乱的情况.
这里之所以采用C和C++混合编程,是因为业务需要. ATS插件目前设计为一个transform主框架, 外加若干子模块, 一个子模块一个动态库,后者可以根据不同业务需要进行扩展,而transform类型的插件框架一般不变, 它只完成通常的transform变换流程就可以了. 这个主框架是使用C++开发的, 它提供了业务实现接口, 供每个业务动态库实现.因为接口入参中用到了stl的map结构来在主框架和子模块之间传递参数,所以接口的实现必须是C++方式的. 但是我的一个业务插件原来是使用纯c编写的, 引用了几个第三方库,比如JSON, libz, pcre库等, 它们原来已经用C编写好了,并且经过测试发现是可靠的, 如果再换为C++实现一般不太现实, 也没有必要. 这样造成的局面就是, 目前只能C和C++进行混合编程, 对C提供的接口, 要在h文件中使用 extern "C"声明, 并将实现存放在对应的c文件中.(这里必须要分离成两个文件, 如果以前只有一个h文件就搞定的, 现在要分为h和c文件).在编译出一个so时, 同时要外链其他的第三方基础库时, Makefile的编写通常有些技巧的, 请参见我的博文
C和C++混合编程的Makefile的编写!
这种情况下, 对C那部分的调用,我采用malloc和free来分配和释放内存, 对上层接口那部分, 我在主cpp文件中使用new和delete来分配内存.这里明显使得内存的使用更加复杂化了,但是不管怎样,按理说这种做法还是行得通的.
但是在调试过程中,我却发现了一个内存越界的错误, 每次提示的错误都不一样, 但是显示出错的位置又没有明显的错误, 真是让人摸不到头脑, 搞不定了, 郁闷, 失败至极.....
二.内存错误出现的表象
两天的搜索无果, 让我只能寻求内存检测软件的帮助. 我以前用过tcmalloc, 就是google的gperftools里面的一个工具,它会将系统默认的内存分配释放函数替换为自己的函数再进行检测,但是在这里不方便施展, 因为这里new和malloc都用上了, 所以我决定使用valgrind来检测. 具体安装使用方法,请参见
在Ubuntu 14.04 64bit上安装Valgrind并检查内存泄露
下面是ATS插件运行中崩溃时valgrind检测的几个错误截图
该截图告诉我们, pool_alloc(在mem_manage.c第17行)调用malloc分配了1813字节内存, find_replace_html(位于main.cpp第484行)函数使用memcpy从1808处开始要复制8个字节, 而事实上只能复制4字节,这会内存越界,导致非法的8字节写入(越界写入).
该截图告诉我们, pool_alloc(在mem_manage.c第17行)调用malloc分配了1813字节内存,pcre_exec(在 regex_lookup.h第45行)在1813字节后面越界读取了1个字节.
该截图告诉我们, 在分配的1813字节内部的1808字节处, 要非法读取8字节内存(越界读取)
三.内存错误的分析和确定
上面的截图分析, 很明确地传递出内存越界读取和越界写入的错误, 但是我查看内存分配的地方, 没有看到明显的错误.但是多次调试显示的内存错误大多显示到memset这样的地方, 将部分memset代码注释掉后, 程序能运行, 但是运行一段时间后,它还是会有段错误, 看来找到的位置不对, 而且上面截图显示的都是造成错误的表现, 不是真正造成内存出错的地方.最后经过认真理解valgrind的错误提示, 和仔细地分析代码, 终于定位到内存错误的真正地方不是malloc长度那里, 而是memset那里, 初始化内存的那个指针只能是一个void*或char*, 不能是一个结构体, 这就是内存错误的真正地方.
参见下面的截图, 有内存错误的源码截图
改正内存错误的源码截图
改正后, 重新编译调试, 一切正常, 运行很长时间, 都没有再崩掉, 再次印证修改是正确的.而这个错误, 是一个大家看起来很可笑的问题, 所要大家编写代码时还是要提高修养和注意力,千万不要马虎写代码,否则会害死自己的.
四.回顾反思
bug不可怕, 犯错不可耻, 但是仔细分析导致bug的原因, 吸取教训并避免再犯才是最重要的. 另外一点是, 排错的锻炼和快速定位是一项职业素养, 越修bug越有收获越能提高, 经历越丰富自信心越强, 所以bug来了,我们还是得从容面对.
使用valgrind检测ATS插件中的内存泄露相关推荐
- ios代码中的内存泄露,内存检测工具leaks 检测不出来
iphone开发过程中,代码中的内存泄露我们很容易用内存检测工具leaks 检测出来,并一一改之,但有些是因为ios 的缺陷和用法上的错误,leaks 检测工具并不能检测出来,你只会看到大量的内存被使 ...
- Android稳定性系列-01-使用 Address Sanitizer检测原生代码中的内存错误
前言 想必大家曾经被各种Native Crash折磨过,本地测试没啥问题,一到线上或者自动化测试就出现各种SIGSEGV.SIGABRT.SIGILL.SIGBUS.SIGFPE异常,而且堆栈还是崩溃 ...
- Linux下几款C++程序中的内存泄露检查工具
Linux下编写C或者C++程序,有很多工具,但是主要编译器仍然是gcc和g++.最近用到STL中的List编程,为了检测写的代码是否会发现内存泄露,了解了一下相关的知识. 所有使用动态内存分配(dy ...
- vs调试c语言检查内存泄露,VisualStudio中检查内存泄露方法
项目工程中存在内存泄露,被折磨了一晚上,终于查了出来,因为之前没有相关的经验,还比较生疏,在此记录下来,方便以后查找. 对于malloc出的内存的检测方法 这篇文章中详细地记录了从检查到找到确定位置到 ...
- go技术日报(2021-10-20)——定位并修复 Go 中的内存泄露
每日一谚:Go trusts the programmer to write down what is meant. go中文网每日资讯--2021-10-20 一.Go语言中文网 不要写破坏性的 G ...
- LeakCanary——消除Android中的内存泄露
2019独角兽企业重金招聘Python工程师标准>>> ##LeakCanary ####简介 LeakCanary是Square公司最近公布的开源项目,旨在消除Android中的内 ...
- LeakCanary——直白的展现Android中的内存泄露
之前碰到的OOM问题,终于很直白的呈现在我的眼前:我尝试了MAT,但是发现不怎么会用.直到今天终于发现了这个新工具: 当我们的App中存在内存泄露时会在通知栏弹出通知: 当点击该通知时,会跳转到具体的 ...
- Java中的内存泄露的几种可能
转载自 Java中的内存泄露的几种可能 Java内存泄漏引起的原因: 内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏. 长生命周 ...
- 如何在iPhone应用中避免内存泄露
本篇文章将介绍几个在iPhone APP中避免内存泄露的小技巧 关于所有权 所有权是iPhone内存管理的核心思想,对象的所有者负责在使用完对象后进行释放.一个对象可以有多个所有者,当它没有所有者时将 ...
最新文章
- 解决:AttributeError: ‘Graph‘ object has no attribute ‘number_of_selfloops‘
- GitHub上的这本开源算法书火爆了
- cart2pol函数
- 夜深人静,想规划一下短期
- ElementUI:文本框实现远程搜索的用法
- 软件工程基础知识--需求分析
- Redis的下载与安装——Windows版
- 2016年U盘启动盘制作工具哪个好用?看U盘启动盘排行榜!
- PX4模块设计之十二:High Resolution Timer设计
- 谈谈我对服务网格的理解
- 专业测试-自评抑郁量表SDS_悟sphenic_新浪博客
- 55句史上最伤人的语录集:看完一阵心酸啊
- Appium自动化测试元素定位方式
- 电脑的“应用与浏览器控制”出现黄色感叹号
- 考研英语不熟悉的词义(List16-List20)
- deepstream系列gst-shark工具分析插件效率
- MongoDB 3.2.7 for rhel6.4 副本集-分片集群部署
- Java数组,集合,列表的使用与区别
- 关于 web 性能的思考与分享[04]——页面 SEO 优化方案
- 南邮Android软件设计报告,南京邮电大学软件设计实验报告
热门文章
- 2022-2028年中国绝缘栅双极晶体管(IGBT)行业投资分析及前景预测报告
- Linux 终端推荐 Terminator
- 1.低权限的程序向高权限的程序发消息 2.慎用setcurrentdirectory
- 【原创】Cookie应用(二)
- linux安装vsftpt服务,centos安装vsftp服务.md
- 学校计算机机房好处,浅谈学校计算机机房维护
- oracle cdc 提交顺序,Oracle CDC部署流程
- 软件测试黑盒测试实验心得_软件测试的基础知识
- linux部分基础命令总结,Linux 基础命令总结3
- 该文件 linux命令,Linux网络系统,如果执行行命令#chmod 746 file.txt,那么该文件的权限是?...