找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3389|回复: 0
收起左侧

内存泄露问题的解决过程

[复制链接]
ID:113276 发表于 2016-4-10 20:17 | 显示全部楼层 |阅读模式
测试中发现有内存泄露的情况,通过增加内存的信息通过TCP输出的 2301端口debug后发现
  异常的如下
总内存数(字节):6144
已用内存(字节):5816
剩余内存数(字节):328
使用标示:1
正常的如下
总内存数(字节):6144
已用内存(字节):20
剩余内存数(字节):6124
使用标示:1
显然memalloc使内存溢出查找代码因为除了SMTP应用程序使用malloc外其他不具有使用的情况。
所以肯定是SMTP出问题
进一步分析代码为SMTP的smtp_send_mail()中
smtp_send_mail_alloced(struct smtp_session *s)
函数使用的
s = (struct smtp_session *)SMTP_STATE_MALLOC((mem_size_t)mem_len);
分配了一块内存没有事正常的释放。
这样反复
几次最终导致这块应用代码不能正常返回一块完整的 mem_le大小的内存块而一直保留了328字节的剩余内存。
这最终导致了所有依赖mem的应用程序全部获取不到足够的内存块。而出现的内存溢出。
继续分析 释放的内存句柄  (struct smtp_session *) s
发现几处问题

1)非正常中止        “风险”
   if (smtp_verify(s->to, s->to_len, 0) != ERR_OK) {
    return ERR_ARG;
  }
  if (smtp_verify(s->from, s->from_len, 0) != ERR_OK) {
    return ERR_ARG;
  }
  if (smtp_verify(s->subject, s->subject_len, 0) != ERR_OK) {
    return ERR_ARG;
  }
  由于没有对  smtp_send_mail_alloced 函数进行判断所以如果此处返回会造成函数不能正常中止
  也就会导致 (struct smtp_session *) s        没有机会释放(因为在不正常中止时是在后面处理的)
  但是考虑到源数据是固定的从片上flash中取得的,这种几率几乎没有。但是存在风险。所以统一改为
  if (smtp_verify(s->to, s->to_len, 0) != ERR_OK) {
             err = ERR_ARG;
     goto leave;
  }
  if (smtp_verify(s->from, s->from_len, 0) != ERR_OK) {
             err = ERR_ARG;
     goto leave;
  }
  if (smtp_verify(s->subject, s->subject_len, 0) != ERR_OK) {
             err = ERR_ARG;
     goto leave;
  }

  2)、非正常TCP连接,主要原因。
  原来的函数为:
  if(tcp_bind(pcb, IP_ADDR_ANY, SMTP_PORT)!=ERR_OK)
        {
        return        ERR_USEl;
            
        }
  显然还是同样的会造成malloc 分配了但是没有被调用,修改为
  if(tcp_bind(pcb, IP_ADDR_ANY,SMTP_PORT)!=ERR_OK)
  {
        err = ERR_USE;
    goto leave;                  
  }

   这样          leave中就会自动处理释放掉这个非正常中止的而造成的内存的溢出问题。
   leave:
  smtp_free_struct(s);
  return err;

归根结底是一个问题。那就是必须保证malloc 和free 成对出现。
实际验证时发现就是tcp_bind的时反回了(在100K以上的压力数据下)


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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