سؤال

أقوم بتصميم بروتوكول (في 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);
    }

تمكنت من العثور على أن الخط: تحقق (CNET_WRITE_PHYSICAL (الرابط ، (void *) f ، (size_t *) f-> length)) ؛ يسبب Segfault لكن لا يمكنني معرفة السبب. أي مساعدة يحظى بتقدير كبير.

هل كانت مفيدة؟

المحلول

أعتقد أنه المعلمة الثالثة. جرب هذا:

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

في هذا السطر ، أفترض أن المعلمة الثالثة تتوقع مؤشرًا ، لأنك تلقي قيمة إلى أ (size_t *). لكن القيمة التي تقوم بها هي قيمة عدد صحيح بسيط. لذلك ، كلما تخلت الوظيفة العنوان الوارد في هذه القيمة ، يكون عندما تحصل على SIGSEGV.

مع الكود الذي اقترحته ، أنت تلقي مؤشرًا (&f->length). لذلك يجب أن تكون على ما يرام ، على افتراض أن الوظيفة تتوقع بشكل فعال مؤشر لمتغير يحمل الحجم.

نصائح أخرى

أرى مشكلتين هنا - sizeof(f) يمنحك حجم أ مؤشر ليس Frame, ، ثم تقوم بتعيين size_t-القيمة المغطاة بـ f->length, ، ولكن في وقت لاحق يلقي بها ل size_t*. هذا الأخير هو على الأرجح سبب خطأ التجزئة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top