Вопрос

After I start using getaddrinfo() to retrieve dynamic IP addresses, the sendTo() of my socket no longer works and returns error "Segmentation fault (core dumped)". Why is that happening, is there any initialization or memory allocation missing in my codes please? I've tried quite a while but haven't figured out the reason. Any help would be really appreciated!

Here is the portion of codes :

    // variables declaration
    int s;
    struct sockaddr_in si_other;
    struct addrinfo hints;     
    struct addrinfo *result, *rp;
    char *hostname = "localhost"; 
    const char* portnum = "8000"; 

    // settings of hints
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
    hints.ai_flags = 0;
    hints.ai_protocol = 0;
    hints.ai_flags = AI_NUMERICSERV;

    // resolve dynamically IP adress by getaddrinfo()
    s = getaddrinfo(hostname, NULL, &hints, &result); 
    if (s != 0) {
            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));exit(EXIT_FAILURE);
    }
    // create socket s
    for (rp = result; rp != NULL; rp = rp->ai_next) 
    {
            s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
    }

    // loop for sending m x struct ECA_message_t 
    int m=0;
for (; m<NbMesPerFile; ++m) 
    {

            ECA_message_t* ECA_paquet;
            ECA_paquet=(ECA_message_t*)malloc(sizeof(ECA_message_t)*2400); 
            // 2400 to workaround some not understood memory issue and make sendto() to 
            // work  

            // function initializing ECA_paquet
            Client_update_ECA_data(ECA_paquet,m);
            if (sendto(s, ECA_paquet, sizeof(ECA_paquet)*2400, 0 ,(struct 
                  sockaddr*)&si_other,slen)==-1)
    {
        perror("sendto()");
    }
    }

To add details to my struct, and to find why my malloc(sizeof(ECA_message_t) goes wrong, please see below the codes for struct ECA_message_t :

typedef struct{

unsigned int version:2;
unsigned int p:1;
unsigned int x:1;
unsigned int cc:4;
unsigned int m:1;
unsigned int pt:7;
unsigned int seq:16;
u_int32_t timestamp;
u_int32_t ssrc;
u_int32_t csrc;
} RTP_header_t;             // 16 bytes


typedef struct {

unsigned int version:2;
unsigned int reserved_1:6;
unsigned int reserved_2:8;
unsigned int number_sample:16;

}ECA_header_t;              // 4 bytes

typedef struct {

//every line composed of 6 values, 2 byte per value, all signed
int32_t v_phase_1;
int32_t v_phase_2;
int32_t v_phase_3;
int32_t i_phase_1;
int32_t i_phase_2;
int32_t i_phase_3;

}ECA_payload_t;             // 12 bytes

typedef struct {

RTP_header_t rtp_header;
ECA_header_t eca_header;
ECA_payload_t eca_payload[MAX_ECA_SAMPLES]; // MAX_ECA_SAMPLES of 100

}ECA_message_t;             // 1220 bytes

Here is the Aborted (Core dumpted) Back trace message :

*** glibc detected *** ./clientUDPIniDyn: double free or corruption (!prev): 0x081768c8 ***
 ======= Backtrace: =========
 /lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb7642ee2]
 ./clientUDPIniDyn[0x804896b]
 /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb75e64d3]
 ./clientUDPIniDyn[0x80486b1]
 ======= Memory map: ========
 08048000-0804a000 r-xp 00000000 08:01 1319522    /home/lin/ULB/Memoire/Client_Server
 /Server/clientUDPIniDyn
 0804a000-0804b000 r--p 00001000 08:01 1319522    /home/lin/ULB/Memoire/Client_Server
 /Server/clientUDPIniDyn
 0804b000-0804c000 rw-p 00002000 08:01 1319522    /home/lin/ULB/Memoire/Client_Server
 /Server/clientUDPIniDyn
 08176000-08197000 rw-p 00000000 00:00 0          [heap]
 b7589000-b75a5000 r-xp 00000000 08:05 264147     /lib/i386-linux-gnu/libgcc_s.so.1
 b75a5000-b75a6000 r--p 0001b000 08:05 264147     /lib/i386-linux-gnu/libgcc_s.so.1
 b75a6000-b75a7000 rw-p 0001c000 08:05 264147     /lib/i386-linux-gnu/libgcc_s.so.1
 b75bf000-b75ca000 r-xp 00000000 08:05 293796     /lib/i386-linux-gnu/libnss_files-
 2.15.so
 b75ca000-b75cb000 r--p 0000a000 08:05 293796     /lib/i386-linux-gnu/libnss_files-
 2.15.so
 b75cb000-b75cc000 rw-p 0000b000 08:05 293796     /lib/i386-linux-gnu/libnss_files-
 2.15.so
 b75cc000-b75cd000 rw-p 00000000 00:00 0 
 b75cd000-b7770000 r-xp 00000000 08:05 293791     /lib/i386-linux-gnu/libc-2.15.so
 b7770000-b7771000 ---p 001a3000 08:05 293791     /lib/i386-linux-gnu/libc-2.15.so
 b7771000-b7773000 r--p 001a3000 08:05 293791     /lib/i386-linux-gnu/libc-2.15.so
 b7773000-b7774000 rw-p 001a5000 08:05 293791     /lib/i386-linux-gnu/libc-2.15.so
 b7774000-b7777000 rw-p 00000000 00:00 0 
 b778d000-b7791000 rw-p 00000000 00:00 0 
 b7791000-b7792000 r-xp 00000000 00:00 0          [vdso]
 b7792000-b77b2000 r-xp 00000000 08:05 293804     /lib/i386-linux-gnu/ld-2.15.so
 b77b2000-b77b3000 r--p 0001f000 08:05 293804     /lib/i386-linux-gnu/ld-2.15.so
 b77b3000-b77b4000 rw-p 00020000 08:05 293804     /lib/i386-linux-gnu/ld-2.15.so
 bfbad000-bfbce000 rw-p 00000000 00:00 0          [stack]
 Aborted (core dumped)
Это было полезно?

Решение 2

// create socket s
for (rp = result; rp != NULL; rp = rp->ai_next) 
{
        s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
}

You are leaking filedescriptors (sockets) here. With every iteration of the loop s is reassigned. And the previous value of s is lost. (I don't know how long your linked list is)

// loop for sending m x struct ECA_message_t 
int m=0;
for (; m<NbMesPerFile; ++m) 
    {

            ECA_message_t* ECA_paquet;
            ECA_paquet=(ECA_message_t*)malloc(sizeof(ECA_message_t)*2400); 
            // 2400 to workaround some not understood memory issue and make sendto() to 
            // work  

            // function initializing ECA_paquet
            Client_update_ECA_data(ECA_paquet,m);
            if (sendto(s, ECA_paquet, sizeof(ECA_paquet)*2400, 0 ,(struct 
                  sockaddr*)&si_other,slen)==-1)
    {
        perror("sendto()");
    }
}

You are leaking memory here. With every iteration of the loop ECA_paquet is reassigned. And the previous value of ECA_paquet is lost. Forever. (I don't know how large NbMesPerFile is)

(this is probably not the cause of your segfault, but it at least indicates substandard quality) You should also not cast the return value of malloc(), (+ #include <stdlib.h>, , plus check malloc()s return value. And turn up the warning level of your compiler.

Другие советы

Here are fixed codes, no more segmentation fault by using calloc()

for (rp = result; rp != NULL; rp = rp->ai_next) 
{
     s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); // socket creation

     ECA_message_t* ECA_paquet;
     ECA_paquet=calloc(NbMesPerFile, sizeof(* ECA_paquet)); // calloc to assign table [NbMesPerFile] length bloc memory for my struct EA_message_t

     // sending m paquets of my struct 
     int m=0;
     for (; m<NbMesPerFile; ++m) 
     {

         Client_update_ECA_data(ECA_paquet,m);  //update the ECA data paquet

         if (sendto(s,ECA_paquet, sizeof(*ECA_paquet) ,0, rp->ai_addr,rp->ai_addrlen)==-1) // send data ECA data pointed by ECA_paquet
         {
             perror("sendto()");
         }
     }

}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top