[uCOS/RTOS] 分享一个结构体不匹配 bug 调试过程

[复制链接]
1369|0
 楼主| 风信子1314 发表于 2019-6-25 09:58 | 显示全部楼层 |阅读模式
本帖最后由 风信子1314 于 2019-6-25 09:59 编辑

分享一个结构体不匹配 bug 调试过程

前段时间在 lwIP151 版本上对接 RT-Thread Netdev 组件(netdev 组件),因为用到 IPV6 和 IPV4,但当时 netdev 并未支持 IPV6,导致 netdev.h 中的 struct netdev 结构体在 lwip 头文件下和 netdev 头文件下结构体大小不一致。

为什么会有这个问题?请看 netdev 数据结构:

  1. struct netdev
  2. {
  3.     rt_slist_t list;
  4.    
  5.     char name[RT_NAME_MAX];                            /* network interface device name */
  6.     ip_addr_t ip_addr;                                 /* IP address */
  7.     ip_addr_t netmask;                                 /* subnet mask */
  8.     ip_addr_t gw;                                      /* gateway */
  9.     ip_addr_t dns_servers[NETDEV_DNS_SERVERS_NUM];     /* DNS server */
  10.     uint8_t hwaddr_len;                                /* hardware address length */
  11.     uint8_t hwaddr[NETDEV_HWADDR_MAX_LEN];             /* hardware address */
  12.    
  13.     uint16_t flags;                                    /* network interface device status flag */
  14.     uint16_t mtu;                                      /* maximum transfer unit (in bytes) */
  15.     const struct netdev_ops *ops;                      /* network interface device operations */
  16.    
  17.     netdev_callback_fn status_callback;                /* network interface device flags change callback */
  18.     netdev_callback_fn addr_callback;                  /* network interface device address information change callback */

  19. #ifdef RT_USING_SAL
  20.     void *sal_user_data;                               /* user-specific data for SAL */
  21. endif /* RT_USING_SAL */
  22.     void *user_data;                                   /* user-specific data */
  23. };
如上,数据结构中包含 ip_addr_t 数据成员,就是该 ip_addr_t 数据结构导致的问题,分析如下:

1. ip_addr_t 数据结构在 netdev 中的定义:

所在头文件 netdev_ipaddr.h
  1. #if NETDEV_IPV4
  2. struct in_addr
  3. {
  4.     in_addr_t s_addr;
  5. };

  6. typedef struct ip4_addr
  7. {
  8.     uint32_t addr;
  9. } ip4_addr_t;

  10. typedef ip4_addr_t ip_addr_t;
  11. #endif /* NETIF_IPV4 */

2. ip_addr_t 在 lwip 中的定义:

所在头文件:lwip/ip_addr.h
  1. #if LWIP_IPV4 && LWIP_IPV6
  2. /** A union struct for both IP version's addresses.
  3. * ATTENTION: watch out for its size when adding IPv6 address scope!
  4. */
  5. typedef struct _ip_addr {
  6.     union {
  7.         ip6_addr_t ip6;
  8.         ip4_addr_t ip4;
  9.     } u_addr;
  10.     u8_t type;
  11. } ip_addr_t;


通过上面两个 ip_addr_t 结构对比,就发现问题了(因为我需要同时支持 IPV4 和 IPV6):

在 lwip 中创建 netdev 设备的时候(ethernetif.c 中创建),使用的是 lwip/ip_addr.h 中的 ip_addr_t,而在 netdev 中使用的是 netdev_ipaddr.h 中的 ip_addr_t,因此两边操作的 netdev 数据结构不一致,导致访问 netdev 数据结构中的数据成员出现莫名奇妙的数据访问错误。

在定位该问题的时候并没有这里写的那么简单,具体过程可以看我博客里的记录。调试过程记录 https://blog.csdn.net/u012349679/article/details/92645870





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

本版积分规则

个人签名:主页:http://murphy.tech 公众号:物联网学前班

7

主题

21

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部