找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 11298|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

lwIP bug 導致程序崩潰問題的解決

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:419956 發(fā)表于 2018-11-2 23:21 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本人使用的LWIP版本號是LWIP 1.3.2 ,并且使用UCOSII  V2.89系統(tǒng)。

在移植使用的過程中,使用LWIP只做客戶端或服務(wù)端是沒有問題的。

后來客戶端和服務(wù)端都集合使用的時候,碰到了一個BUG,
for(pcb =tcp_active_pcbs; pcb != NULL; pcb = pcb->next) , 在這個地方進入死循環(huán)了,
pcb 塊申請和釋放的時候出錯了,pcb->net指向自己本身了。后來在網(wǎng)上查了一大堆資料,
說是LWIP1.3.2版本就有這個問題,而1.4.1版本沒有。

為了解決這個問題就嘗試去移植LWIP1.4.1這個版本,然后卻發(fā)現(xiàn)1.4.11.3.2版本的郵箱和信號
量函數(shù)接口都不同了,在UCOSII,V2.8.9下已經(jīng)不能滿足了。相當于之前移植的sys_arch.c已經(jīng)
不能適應(yīng)了。LWIP1.4.1在網(wǎng)上的sys_arch.c例子基本都是基于UCOSIII-V3.0.x 來實現(xiàn)。所有如果
更換LWIP1.4.1的話,最好也要去替換UCOSII。而又由于之前的工程中已有使用UCOSII,再去替
換工作量又相當大,所有想找到一種方式,直接在LWIP1.3.2版本下解決LWIPpcb->net指向自己
本身的問題。

后來發(fā)現(xiàn)這個問題是由于LWIP里面的TCP塊在沒有接連的情況下,不用close就會自動釋放。如果LWIP
自己釋放過了,而你自己又操作closeabort釋放一次,那么TCP_PCB內(nèi)存塊就出現(xiàn)問題了。那么問題
既然找到了,那就想辦法解決。本人想到了一個修改最少最簡便的方法來解決這個問題,僅需修改
2.c、1.h文件即可解決這個問題。修改情況如下:


  
需改內(nèi)容
  
解釋
文件名稱
添加內(nèi)容(增加紅色字體)
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 結(jié)構(gòu)體中增加一個字段,pcb_used。這個字段值 = 0 = 1
  
0代表這個TCP_PCB塊沒有在使用,已經(jīng)釋放。
  
1代表這個TCP_PCB塊正在使用,占用內(nèi)存。
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塊已經(jīng)釋放過了,可能是沒連接的塊系統(tǒng)自己釋放,也能是自己誤操作,多次釋放?傊还苁裁丛,已經(jīng)釋放過的不能再釋放了,所有這邊直接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,標記這個塊目前正在使用,占用內(nèi)存。


現(xiàn)在只需要在,structtcp_pcb中添加一個字段,再加上幾行代碼,就可以解決這個問題了。


評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:275111 發(fā)表于 2019-8-27 11:18 | 只看該作者
佩服。真厲害呀。真在學習LWIP。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表