找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9785|回复: 1
打印 上一主题 下一主题
收起左侧

lwIP bug 导致程序崩溃问题的解决

[复制链接]
跳转到指定楼层
楼主
ID:419956 发表于 2018-11-2 23:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人使用的LWIP版本号是LWIP 1.3.2 ,并且使用UCOSII  V2.89系统。

在移植使用的过程中,使用LWIP只做客户端或服务端是没有问题的。

后来客户端和服务端都集合使用的时候,碰到了一个BUG
for(pcb =tcp_active_pcbs; pcb != NULL; pcb = pcb->next) 在这个地方进入死循环了,
pcb 块申请和释放的时候出错了,pcb->net指向自己本身了。后来在网上查了一大堆资料,
说是LWIP1.3.2版本就有这个问题,而1.4.1版本没有。

为了解决这个问题就尝试去移植LWIP1.4.1这个版本,然后却发现1.4.11.3.2版本的邮箱和信号
量函数接口都不同了,在UCOSIIV2.8.9下已经不能满足了。相当于之前移植的sys_arch.c已经
不能适应了。LWIP1.4.1在网上的sys_arch.c例子基本都是基于UCOSIII-V3.0.x 来实现。所有如果
更换LWIP1.4.1的话,最好也要去替换UCOSII。而又由于之前的工程中已有使用UCOSII,再去替
换工作量又相当大,所有想找到一种方式,直接在LWIP1.3.2版本下解决LWIPpcb->net指向自己
本身的问题。

后来发现这个问题是由于LWIP里面的TCP块在没有接连的情况下,不用close就会自动释放。如果LWIP
自己释放过了,而你自己又操作closeabort释放一次,那么TCP_PCB内存块就出现问题了。那么问题
既然找到了,那就想办法解决。本人想到了一个修改最少最简便的方法来解决这个问题,仅需修改
2.c1.h文件即可解决这个问题。修改情况如下:


  
需改内容
  
解释
文件名称
添加内容(增加红色字体)
tcp.h
/* the TCP protocol control block */
  
struct tcp_pcb {
  
/** common PCB members */
  
   IP_PCB;
  
/** protocol specific PCB members */
  
   TCP_PCB_COMMON(struct tcp_pcb);
  
..............................省略......................................
  
  
   /* KEEPALIVE counter */
  
   u8_t keep_cnt_sent;
  
  
  u8_t pcb_used;
  
};
struct  tcp_pcb 结构体中增加一个字段,pcb_used。这个字段值 = 0 = 1
  
0代表这个TCP_PCB块没有在使用,已经释放。
  
1代表这个TCP_PCB块正在使用,占用内存。
memp.c
void
  
memp_free(memp_t type, void *mem)
  
{
  
   struct memp *memp;
  
  struct tcp_pcb *pcb;
  
  if(type == MEMP_TCP_PCB ){
  
      pcb  = (struct tcp_pcb *)mem;
  
       if(pcb->pcb_used == 0){
  
              return;
  
       }
  
       pcb->pcb_used = 0;
  
  }
  
   SYS_ARCH_DECL_PROTECT(old_level);
  
..............................省略......................................
  
SYS_ARCH_UNPROTECT(old_level);
  
}
在释放TCP_PCB块的时候,如果pcb_used==0,那么这个TCP_PCB块已经释放过了,可能是没连接的块系统自己释放,也能是自己误操作,多次释放。总之,不管什么原因,已经释放过的不能再释放了,所有这边直接return退出。没有释放的正常释放,只是字段pcb_used0
tcp.c
struct tcp_pcb *
  
tcp_alloc(u8_t prio)
  
{
  
   struct tcp_pcb *pcb;
  
   u32_t iss;
  
  
  
   pcb = memp_malloc(MEMP_TCP_PCB);
  
   if (pcb == NULL) {
  
    ..............................省略......................................
  
  }
  
   if (pcb != NULL) {
  
     memset(pcb, 0, sizeof(struct tcp_pcb));
  
     ..............................省略......................................
  
     pcb->keep_cnt_sent = 0;
  
       pcb->pcb_used = 1;
  
  }
  
   return pcb;
  
}
在申请TCP_PCB块的时候,把pcb_used1,标记这个块目前正在使用,占用内存。


现在只需要在,structtcp_pcb中添加一个字段,再加上几行代码,就可以解决这个问题了。


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:275111 发表于 2019-8-27 11:18 | 只看该作者
佩服。真厉害呀。真在学习LWIP。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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