打印
[uCOS/RTOS]

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

[复制链接]
1111|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 数据结构:

struct netdev
{
    rt_slist_t list;
   
    char name[RT_NAME_MAX];                            /* network interface device name */
    ip_addr_t ip_addr;                                 /* IP address */
    ip_addr_t netmask;                                 /* subnet mask */
    ip_addr_t gw;                                      /* gateway */
    ip_addr_t dns_servers[NETDEV_DNS_SERVERS_NUM];     /* DNS server */
    uint8_t hwaddr_len;                                /* hardware address length */
    uint8_t hwaddr[NETDEV_HWADDR_MAX_LEN];             /* hardware address */
   
    uint16_t flags;                                    /* network interface device status flag */
    uint16_t mtu;                                      /* maximum transfer unit (in bytes) */
    const struct netdev_ops *ops;                      /* network interface device operations */
   
    netdev_callback_fn status_callback;                /* network interface device flags change callback */
    netdev_callback_fn addr_callback;                  /* network interface device address information change callback */

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

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

所在头文件 netdev_ipaddr.h
#if NETDEV_IPV4
struct in_addr
{
    in_addr_t s_addr;
};

typedef struct ip4_addr
{
    uint32_t addr;
} ip4_addr_t;

typedef ip4_addr_t ip_addr_t;
#endif /* NETIF_IPV4 */

2. ip_addr_t 在 lwip 中的定义:

所在头文件:lwip/ip_addr.h
#if LWIP_IPV4 && LWIP_IPV6
/** A union struct for both IP version's addresses.
* ATTENTION: watch out for its size when adding IPv6 address scope!
*/
typedef struct _ip_addr {
    union {
        ip6_addr_t ip6;
        ip4_addr_t ip4;
    } u_addr;
    u8_t type;
} 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

粉丝