搜索
bottom↓
回复: 14

求助:如何定位内存泄露的位置

[复制链接]

出0入0汤圆

发表于 2014-5-29 10:01:33 | 显示全部楼层 |阅读模式
程序跑一段时间,就会出现堆溢出造成线程超时的情况。而且每次max_mem只超过了mem_size_aligned 8个字节。我尝试扩大堆的大小,依然会出现这种情况而且同样只超过8个字节。溢出所需的时间从半天到2天不等,没看出什么规律。造成堆溢出的原因就是在超时的那个线程中么,还是其他地方也有可能?有谁知道定位哪里造成内存泄露的方法么?用眼睛看真是不好找。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2014-5-29 10:44:45 | 显示全部楼层
补充一点,我用的rt-thread系统版本为1.1.0.刚才又查看了下程序,我申请的线程,邮箱,信号量等都用的是init是静态的。全局查看了一下malloc 函数,只发现在lwip,finsh和rt-thread中使用。不知道最新版本的rt-thread系统是否有定位内存泄露的方法,或者使用最新版本的rt-thread系统和lwip会更加稳定一点。

出0入0汤圆

发表于 2014-5-29 11:15:51 | 显示全部楼层
在哪个线程都有可能,停掉怀疑的线程或者在malloc函数里打调试信息

出0入0汤圆

 楼主| 发表于 2014-5-29 11:27:09 | 显示全部楼层
netawater 发表于 2014-5-29 11:15
在哪个线程都有可能,停掉怀疑的线程或者在malloc函数里打调试信息

所有申请堆空间用的都是rt_malloc()这个函数么,malloc 函数中打印那些信息有助于确定内存泄露的位置呢?

出0入0汤圆

发表于 2014-5-29 12:51:18 | 显示全部楼层
tyj07 发表于 2014-5-29 11:27
所有申请堆空间用的都是rt_malloc()这个函数么,malloc 函数中打印那些信息有助于确定内存泄露的位置呢? ...

打印每次malloc的大小和分配到的地址。

发现规律后,如果能断点的话,就在断下来看是在哪里调用的。不能断点就得打印堆栈中函数返回地址,确定是哪里调用的。

出0入0汤圆

发表于 2014-5-29 13:28:15 | 显示全部楼层
查下数据copy是否越界

出0入0汤圆

发表于 2014-5-29 14:26:16 | 显示全部楼层
list_mem()命令查看内存增长的顺序

出0入0汤圆

 楼主| 发表于 2014-5-29 14:33:29 | 显示全部楼层
netawater 发表于 2014-5-29 12:51
打印每次malloc的大小和分配到的地址。

发现规律后,如果能断点的话,就在断下来看是在哪里调用的。不能 ...

malloc在申请空间的时候会判断是否越界么,有没有一种方法在他越界的时候打印出地址呢?

出0入0汤圆

 楼主| 发表于 2014-5-29 14:39:57 | 显示全部楼层
ffxz 发表于 2014-5-29 14:26
list_mem()命令查看内存增长的顺序

我有用定时器每1分钟调用list_mem打印堆的情况。但list_mem中的max_mem是历史上最大占用堆空间,我也不清楚程序是积累后造成堆溢出,还是某一个时刻把堆挤爆了。而且奇怪的是max_mem只超过mem_size_aligned 8个字节。全局查看了下malloc函数,大部分只在finsh和lwip中使用,就是定位不了是哪里申请后溢出了。

出0入0汤圆

发表于 2014-5-29 14:42:57 | 显示全部楼层
tyj07 发表于 2014-5-29 14:33
malloc在申请空间的时候会判断是否越界么,有没有一种方法在他越界的时候打印出地址呢? ...

起始地址+大小>堆边界 就越界了。

出0入0汤圆

 楼主| 发表于 2014-5-29 15:49:21 | 显示全部楼层
netawater 发表于 2014-5-29 14:42
起始地址+大小>堆边界 就越界了。

在rt-thread中申请堆空间调用的是void *rt_malloc(rt_size_t size)函数么?
我大概看了下函数,如果越界的话应该返回NULL。那么堆溢出的问题又是如何造成的呢?

出0入0汤圆

发表于 2014-5-29 16:25:55 | 显示全部楼层
tyj07 发表于 2014-5-29 15:49
在rt-thread中申请堆空间调用的是void *rt_malloc(rt_size_t size)函数么?
我大概看了下函数,如果越界 ...

你的情况是有个线程把堆都用光了,其它进程申请不到空间就会死循环在那里。

你先找出为什么会把堆用光吧 !

出0入0汤圆

 楼主| 发表于 2014-5-29 16:36:23 | 显示全部楼层
netawater 发表于 2014-5-29 16:25
你的情况是有个线程把堆都用光了,其它进程申请不到空间就会死循环在那里。

你先找出为什么会把堆用光吧 ...

我所有的线程都是rt_thread_init初始化的,都是静态的。应该不占用堆的空间吧?我以前削减过和堆在同一区域的线程的堆栈大小,削减了200字节,堆才增大了10+字节。而且同样会出现溢出的情况,感觉像是哪里申请了堆空间后未释放,又反复申请溢出了。就是不好定位。

出0入0汤圆

发表于 2014-5-30 09:08:11 | 显示全部楼层
tyj07 发表于 2014-5-29 16:36
我所有的线程都是rt_thread_init初始化的,都是静态的。应该不占用堆的空间吧?我以前削减过和堆在同一区 ...

我说了定位方法,你先试再回复,OK?

出0入0汤圆

发表于 2014-5-30 09:36:38 | 显示全部楼层
tyj07 发表于 2014-5-29 16:36
我所有的线程都是rt_thread_init初始化的,都是静态的。应该不占用堆的空间吧?我以前削减过和堆在同一区 ...

一个是查局部的Alloc/Free配对。

如果是分配了空间,作为指针传来传去,基本只能靠生成比较细致的Log,然后写独立的程序分析Log。
需要特别注意把指针挂在另外一个结构体里的情况,释放的时候是不是放了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-30 13:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表