【问题标题】:SIGSEGV problemSIGSEGV 问题
【发布时间】:2010-05-23 03:51:02
【问题描述】:

我正在设计一个协议(用 C 语言)来实现分层 OSI 网络结构,使用 cnet (http://www.csse.uwa.edu.au/cnet/)。我在运行时遇到 SIGSEGV 错误,但是 cnet 会自行编译我的源代码文件(我无法通过 gcc 编译它),因此我无法轻松使用任何调试工具(例如 gdb)来查找错误。

这是使用的结构和相关代码:

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(link, (void *)f, (size_t *)f->length));导致段错误,但我不知道为什么。 非常感谢任何帮助。

【问题讨论】:

    标签: c segmentation-fault


    【解决方案1】:

    我认为是第三个参数。试试这个:

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

    在这一行中,我假设第三个参数需要一个指针,因为您将一个值转换为 (size_t *)。但是您要转换的值是一个简单的整数值。因此,每当函数取消引用该值中包含的地址时,您可能会得到一个 SIGSEGV。

    使用我建议的代码,您正在投射一个指针(&f->length)。所以你应该很高兴,假设函数有效地期待一个指向一个持有大小的变量的指针。

    【讨论】:

    • 您已正确识别问题,但您建议的修复方法在 intsize_t 大小不同的环境中不起作用 - 这在当今相当普遍。跨度>
    • 感谢您的回答和详细的解释。
    【解决方案2】:

    我在这里看到两个问题 - sizeof(f) 给你一个 指针 的大小而不是 Frame,然后你将 size_t-typed 值分配给 f->length,但后来将它转换为size_t*。后者很可能是分段错误的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      • 1970-01-01
      • 2019-06-30
      • 2021-04-10
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      相关资源
      最近更新 更多