2010-05-23 70 views
2

我正在使用cnet(http://www.csse.uwa.edu.au/cnet/)設計一個實現分層OSI網絡結構的協議(在C中)。我在運行時遇到了一個SIGSEGV錯誤,但是cnet自己編譯我的源代碼文件(我無法通過gcc編譯它),所以我不能輕易使用任何調試工具(如gdb)來查找錯誤。SIGSEGV問題

這裏使用的結構,並且有問題的代碼:我設法找到該行

typedef struct { 
    char *data; 
} DATA; 

typedef struct { 
    CnetAddr src_addr; 
    CnetAddr dest_addr; 
    PACKET_TYPE type;   
    DATA data; 
} Packet; 

typedef struct { 
    int length;   
    int checksum; 
    Packet datagram; 
} Frame; 


static void keyboard(CnetEvent ev, CnetTimerID timer, CnetData data) 
    { 
    char line[80]; 
    int length; 

    length = sizeof(line); 
    CHECK(CNET_read_keyboard((void *)line, (unsigned int *)&length)); // Reads input from keyboard 

    if(length > 1) 
     {   /* not just a blank line */ 
     printf("\tsending %d bytes - \"%s\"\n", length, line); 

     application_downto_transport(1, line, &length); 
     } 
    } 

void application_downto_transport(int link, char *msg, int *length) 
    { 
    transport_downto_network(link, msg, length); 
    } 

void transport_downto_network(int link, char *msg, int *length) 
    { 
    Packet *p; 
    DATA *d; 

    p = (Packet *)malloc(sizeof(Packet)); 
    d = (DATA *)malloc(sizeof(DATA)); 

    d->data = msg; 
    p->data = *d; 

    network_downto_datalink(link, (void *)p, length); 
    } 

void network_downto_datalink(int link, Packet *p, int *length) 
    { 
    Frame *f; 

    // Encapsulate datagram and checksum into a Frame. 
    f = (Frame *)malloc(sizeof(Frame)); 

    f->checksum = CNET_crc32((unsigned char *)(p->data).data, *length); // Generate 32-bit CRC for the data. 
    f->datagram = *p; 
    f->length = sizeof(f); 

    //Pass Frame to the CNET physical layer to send Frame to the require link. 
    CHECK(CNET_write_physical(link, (void *)f, (size_t *)f->length)); 
    free(p->data); 
    free(p); 
    free(f); 
    } 

:CHECK(CNET_write_physical(鏈接(無效*)F,(爲size_t *)F - >長度));導致段錯誤,但我無法解決原因。 任何幫助,不勝感激。

回答

2

我認爲是第三個參數。試試這個:

CHECK(CNET_write_physical(link, (void *)f, (size_t *)(&f->length))); 

在這一行,我認爲第三個參數需要一個指針,因爲你鑄造價值爲(size_t *)。但是你正在鑄造的價值是一個簡單的整數值。所以,只要函數取消引用該值中包含的地址,就是在您可能獲得SIGSEGV時。

隨着我建議的代碼,你投了一個指針(&f->length)。所以你應該很好走,假設函數實際上期望指向一個變量的指針。

+0

你已經正確地發現了這個問題,但是你的建議的修復方法在'int'和'size_t'的大小不一樣的環境下是行不通的 - 這些日子相當普遍。 – caf 2010-05-23 07:24:22

+0

感謝您的回答和詳細的解釋。 – sickmate 2010-05-23 12:26:12

0

我在這裏看到了兩個問題 - sizeof(f)給你一個指針不是Frame的大小,那麼你size_t -typed值賦給f->length,但後來將其轉換爲size_t*。後者很可能是分段錯誤的原因。