0

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)
user2212304
  • 13
  • 1
  • 5
  • `ECA_paquet=(ECA_message_t*)malloc(sizeof(ECA_message_t)*2400); if (sendto(s, ECA_paquet, sizeof(ECA_paquet), 0 ,(struct sockaddr*)&si_other,slen)==-1)` You are allocating enough space for 2400 packets and send one. Uninitialised. This will *at least* cause some memory leak. – wildplasser Mar 28 '13 at 20:11
  • "s" isn't declared, the status of getaddrinfo() isn't checked, and the status of socket() isn't checked. Recompile with debugging enabled, get the stack trace, and verify the arguments to sendto(). – Steve Emmerson Mar 28 '13 at 20:15
  • Thank you for replying, @wildplasser : if I allocate only space for one struct ECA_message_t, then I will get erro Aborted (core dumped). I pick a randomly big figure, as 2400 (now down to 40) so to be sure to get enough space. My segmentation problem is now solved but can reapear since I still don't know what's wrong with my memory allocation. Here is the structure of ECA_message_t – user2212304 Mar 28 '13 at 21:24
  • Thank you for replying, @Steve Emmerson : I repaste the entire codes, sorry for missing them first time. Now it works but still can't find where the issue is next time it will happen. – user2212304 Mar 28 '13 at 21:27
  • @Steve Emmerson and @ wildplasser : as requested I add the back trace of my error, it seems I got memory problem at least with stack and heap. But why is it not working? From what I see, my ECA_message_t requires 1220 bytes each time. I declare that with `ECA_paquet = (ECA_message_t*)malloc(sizeof(ECA_message_t)*)` and `sendto(s, ECA_paquet, sizeof(ECA_paquet), 0 ,(struct sockaddr*)&si_other,slen);`. Thank you for pointing out any abnormality – user2212304 Mar 28 '13 at 21:52
  • Are you exceeding the maximum size of a datagram? – Steve Emmerson Mar 28 '13 at 22:42
  • @SteveEmmerson: after the edit he does exceed the size of a datagram. (the original version sent only one struct item) But that would not be a cause for a segve; only sendto returning -1 ... – wildplasser Mar 29 '13 at 00:14
  • @wildplasser Agreed. I'm actually more concerned about the (unchecked) socket-creation leak and the fact that the debugger output doesn't appear to be a stack trace. – Steve Emmerson Mar 29 '13 at 16:00

2 Answers2

1

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

}
user2212304
  • 13
  • 1
  • 5
0
// 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.

wildplasser
  • 43,142
  • 8
  • 66
  • 109
  • Thank you wildplasser and Steve Emmerson, I check the memory leak and numerous other faults, now manage to fix my codes to work properly. The codes are pasted below and do send my struct without seg fault. Thanks – user2212304 Mar 30 '13 at 07:25