clinuxsystems-programming

How to fix the following malloc error in my code?


I am trying to write a program to connect a client and a server using a FIFO on Linux and then when the client sends a message to the server, the server prints that message to the console. Now I designed the program as follows: When the client types something like "Hey, how are you?" a message with some extra info is constructed. The message has the following format: "[PID of client/Size of message:message]". So if the client has the PID of say 4172, then in our example the composed message is: "[4172/17:Hey, how are you?]". This message is sent to the server and the server decomposes it and only prints the message without the extra bits of info like the PID of client etc. Now I included those info in order to not waste memory as that enables me to use dynamic memory allocation. The program works the first time round. The client and server connect and when the client sends its message the server prints it just fine. However when I try to send it a message again, I get the following error :

server.out: malloc.c:2617: sysmalloc: Assertion (old_top == initial_t…
…op (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed. Aborted(core dumped).

The relevant bit of the server code is :

//delimCheckBuffer is an array of size 1

void readUntilColon(int fd, char* buffer, size_t index) {
    while(read(fd, delimCheckBuffer, 1) > 0) {
        if(delimCheckBuffer[0] == ':') {
            buffer[index] = ':';
            break;
        }
        buffer[index] = delimCheckBuffer[0];
        ++index;
    }
}

char* messageReconstruct(int fdOfFIFO) {
    char* message = calloc(15, sizeof(char)); //Took into account the 4 symbols : / [ ] and 
    long NumOfCharsInMessage;                 //assumed that PID and length of message are at most
    size_t index = 0;                         //7 and 4 digits respectively.

    readUntilColon(fdOfFIFO, message, 1);
    NumOfCharsInMessage = findNumOfCharsInMessage(message);
    
    free(message);

    message = calloc(NumOfCharsInMessage, sizeof(char));

    while(read(fdOfFIFO, delimCheckBuffer, 1) > 0) {
        if(delimCheckBuffer[0] == ']')
            break;
        message[index] = delimCheckBuffer[0];
        ++index;
    }

    return message;
}

I tried to debug it with Valgrind. It said invalid write of size 1 at readUntilColon(). It specifically pointed out that buffer[index] = delimCheckBuffer[0]; is the problem. However I still do not understand what is wrong with this bit. It would be great if someone could explain it to me. Thanks.


Solution

  • You need to check if you are not overwriting the buffer

    void readUntilColon(int fd, char* buffer, size_t index, size_t size) {
        while(read(fd, delimCheckBuffer, 1) > 0) {
            if(index < size)
            {
                if(delimCheckBuffer[0] == ':') {
                    buffer[index] = ':';
                    break;
                }
                buffer[index] = delimCheckBuffer[0];
                ++index;
            }
        }
    }
    

    Call it accordingly. Add some more checks