2010-05-23 13 views
2

Je suis la conception d'un protocole (en C) pour mettre en œuvre la structure du réseau OSI en couches, en utilisant cnet (http://www.csse.uwa.edu.au/cnet/). Je reçois une erreur SIGSEGV lors de l'exécution, mais cnet compile mes fichiers de code source lui-même (je ne peux pas le compiler par gcc) donc je ne peux pas utiliser facilement des outils de débogage tels que GDB pour trouver l'erreur.problème SIGSEGV

est ici les structures utilisées, et le code en question:

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); 
    } 

je réussi à trouver que la ligne: CHECK (CNET_write_physical (lien, (void *) f (size_t *) F-> Longueur)); est à l'origine du segfault mais je ne sais pas pourquoi. Toute aide est grandement appréciée.

Répondre

2

Je pense est le troisième paramètre. Essayez ceci:

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

Dans cette ligne, je suppose que troisième paramètre attend un pointeur, parce que vous jettes une valeur à une (size_t *). Mais la valeur que vous lancez est une valeur entière simple. Ainsi, chaque fois que la fonction déréférence l'adresse contenue dans cette valeur, c'est quand vous obtenez probablement un SIGSEGV.

Avec le code que je suggère, vous Jetant un pointeur (&f->length). Donc, vous devriez être bon à partir, en supposant que la fonction attend effectivement un pointeur vers une variable contenant une taille.

+0

Vous avez correctement identifié le problème, mais votre correctif suggéré ne fonctionnera pas dans les environnements où 'int' et' size_t' n'ont pas la même taille - ce qui est assez courant de nos jours. – caf

+0

Merci pour la réponse et l'explication détaillée. – sickmate

0

Je vois deux problèmes ici - sizeof(f) vous donne la taille d'un pointeur pas le Frame, vous attribuez size_t valeur -typed à f->length, mais jeté plus tard à size_t*. Ce dernier est très probablement la cause de la faute de segmentation.

Questions connexes