rtthread 字節對齊問題 int指針訪問非對齊地址崩潰

rtthread 字節對齊問題 int指針訪問非對齊地址崩潰
環境:
SOC: i.MX RT1050
底板: 野火 RT1052
Kernel: rt-thread

背景:
我正在實現解析udp包, 而udp包的結構不是字節對齊的, 這個時候我使用__packed來說明按照1字節對齊, 在解析udp包數據的地方, 取udp->srcaddr這個成員的值的時候, 出現 UNALIGN(未對齊) 錯誤. 我將該問題用以下代碼來複現. 如果有更好的網絡協議數據結構體定義方式, 還請告知, 謝謝

現象:
使用rtthread master版 生成的工程運行後會出現以下問題, 但使用裸機程序, 或者 rtthread nano版 運行後不會出現以下問題. 這個問題還未有答案, 如果有哪位道友, 遇到了, 一起學習探討

/*
        1.內存 堆區
            a.uint32_t* 類型, 所指向的地址必須是四字節對齊
            b.uint16_t* 類型, 所指向的地址必須是兩字節對齊
        2.內存 RW/ZI 區
            a.uint32_t* 類型, 所指向的地址必須是四字節對齊
            b.uint16_t* 類型, 所指向的地址必須是兩字節對齊
        3.DTCM
            a.uint32_t* 類型, 非四字節對齊地址任然可以訪問
            b.uint16_t* 類型, 非兩字節對齊地址任然可以訪問
        4.內存 棧區
            定義一字節對齊結構體, 任意成員可以訪問
        5.內存 棧區 char數組
            a.uint32_t* 類型, 非四字節對齊地址無法訪問
            a.uint16_t* 類型, 非兩字節對齊地址無法訪問
    */
    /* 內存 棧區 char數組 
    __packed char data[128];
    rt_kprintf("&data[0]: %p\n", &data[0]);
    __packed uint32_t* p = (__packed uint32_t*)(&data[0]);
    rt_kprintf("*p: %x\n", *p);
    p = (__packed uint32_t*)(&data[0]+1);
    rt_kprintf("p: %p\n", p);
    rt_kprintf("*p: %x\n", *p);
    
    __packed uint16_t* p2 = (__packed uint16_t*)(data);
    rt_kprintf("*p2: %x\n", *p2);
    p2 = (__packed uint16_t*)(data+1);
    rt_kprintf("*p2: %x\n", *p2);
    p2 = (__packed uint16_t*)(data+3);
    rt_kprintf("*p2: %x\n", *p2);*/
    
    rt_kprintf("sizeof(eth_hdr): %d; sizeof(ip_hdr): %d\n",sizeof(eth_hdr),sizeof(ip_hdr));
    uint8_t* tpoint = (uint8_t*)malloc(60);
    rt_kprintf("tpoint: %p\n", tpoint);
    eth_hdr* ethhdr = (eth_hdr*)tpoint;
    tpoint += sizeof(eth_hdr);
    ip_hdr* iphdr = (ip_hdr*)tpoint;
    rt_kprintf("tpoint: %p\n", tpoint);
    rt_kprintf("iphdr: %p\n", iphdr);
    iphdr->tlen = 0x10;
    rt_kprintf("iphdr->tlen: %x\n", iphdr->tlen);
    rt_kprintf("&iphdr->srcaddr: %p\n", &iphdr->srcaddr);
    iphdr->srcaddr = 0x1111;
    rt_kprintf("iphdr->srcaddr: %x\n", iphdr->srcaddr);
    
    /* 內存 棧區 一字節對齊結構體訪問 
    ip_hdr iphdr;
    iphdr.srcaddr = 0x1111;
    rt_kprintf("sizeof(iphdr): %d\n", sizeof(iphdr));
    rt_kprintf("iphdr.srcaddr: %d\n", iphdr.srcaddr);*/
    
    /* DTCM 0x20000000 
    uint32_t* p = (uint32_t*)0x20000000;
    rt_kprintf("*p: %x\n", *p);
    p = (uint32_t*)0x20000004;
    rt_kprintf("*p: %x\n", *p);
    p = (uint32_t*)0x20000008;
    rt_kprintf("*p: %x\n", *p);
    
    uint16_t* p2 = (uint16_t*)0x20000000;
    rt_kprintf("*p2: %x\n", *p2);
    p2 = (uint16_t*)0x20000002;
    rt_kprintf("*p2: %x\n", *p2);
    p2 = (uint16_t*)0x20000004;
    rt_kprintf("*p2: %x\n", *p2);
    
    p = (uint32_t*)0x20000001;
    rt_kprintf("*p: %x\n", *p);
    p2 = (uint16_t*)0x20000001;
    rt_kprintf("*p2: %x\n", *p2);
    p2 = (uint16_t*)0x20000003;
    rt_kprintf("*p2: %x\n", *p2);*/
    
    /* 內存 RW/ZI 區, 字節對齊測試 
    uint32_t* p = (uint32_t*)0x80200000;
    rt_kprintf("*p: %x\n", *p);
    p = (uint32_t*)0x80200004;
    rt_kprintf("*p: %x\n", *p);
    p = (uint32_t*)0x80200008;
    rt_kprintf("*p: %x\n", *p);
    
    uint16_t* p2 = (uint16_t*)0x80200000;
    rt_kprintf("*p2: %x\n", *p2);
    p2 = (uint16_t*)0x80200002;
    rt_kprintf("*p2: %x\n", *p2);
    p2 = (uint16_t*)0x80200004;
    rt_kprintf("*p2: %x\n", *p2);
    
    p = (uint32_t*)0x80200001;
    rt_kprintf("*p: %x\n", *p);
    p2 = (uint16_t*)0x80200001;
    rt_kprintf("*p2: %x\n", *p2);
    p2 = (uint16_t*)0x80200003;
    rt_kprintf("*p2: %x\n", *p2);*/
    
    
    /* 堆區, 字節對齊測試
    uint32_t* p = (uint32_t*)0x802059a0;
    rt_kprintf("*p: %x\n", *p);
    p = (uint32_t*)0x802059a4;
    rt_kprintf("*p: %x\n", *p);
    p = (uint32_t*)0x802059a8;
    rt_kprintf("*p: %x\n", *p);
    
    uint16_t* p2 = (uint16_t*)0x802059a0;
    rt_kprintf("*p2: %x\n", *p2);
    p2 = (uint16_t*)0x802059a2;
    rt_kprintf("*p2: %x\n", *p2);
    p2 = (uint16_t*)0x802059a4;
    rt_kprintf("*p2: %x\n", *p2);
    
    p = (uint32_t*)0x802059a1;
    rt_kprintf("*p: %x\n", *p);
    p2 = (uint16_t*)0x802059a1;
    rt_kprintf("*p2: %x\n", *p2);
    p2 = (uint16_t*)0x802059a3;
    rt_kprintf("*p2: %x\n", *p2);*/

程序崩潰報錯圖示:
程序崩潰報錯

在 rtthread nano版 中執行 “內存 RW/ZI 區” 測試, 測試結果如下
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章