Search code examples
cmappingposixmap-files

Segmentation fault with Posix-C program using mmap and mapfile


Well I have this program and I get a segmentation fault: 11 (core dumped). After lots of checks I get this when the for loop gets to i=1024 and it tries to mapfile[i]=0. The program is about making a server and a client program that communicates by read/writing in a common file made in the server program. This is the server program and it prints the value inside before and after the change. I would like to see what's going on, if it's a problem with the mapping or just problem with memory of the *mapfile. Thanks!

#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <math.h>

int main()
{
    int ret, i;           
    int *mapfile;           

    system("dd if=/dev/zero of=/tmp/c4 bs=4 count=500");

    ret = open("/tmp/c4", O_RDWR | (mode_t)0600);
    if (ret == -1)
    {
        perror("File");
        return 0;
    }

    mapfile = mmap(NULL, 2000, PROT_READ | PROT_WRITE, MAP_SHARED, ret, 0);

    for (i=1; i<=2000; i++)
    {
        mapfile[i] = 0;
    }

    while(mapfile[0] != 555)
    {
        mapfile = mmap(NULL, 2000, PROT_READ | PROT_WRITE, MAP_SHARED, ret, 0);
        if (mapfile[0] != 0)
        {
            printf("Readed from file /tmp/c4 (before): %d\n", mapfile[0]);
            mapfile[0]=mapfile[0]+5;
            printf("Readed from file /tmp/c4 (after)  : %d\n", mapfile[0]);
            mapfile[0] = 0;
        }
        sleep(1);
    }

    ret = munmap(mapfile, 2000);
    if (ret == -1)
    {
        perror("munmap");
        return 0;
    }

    close(ret);

    return 0;
}

Solution

  • mapfile = mmap(NULL, 2000, PROT_READ | PROT_WRITE, MAP_SHARED, ret, 0);
    
    for (i=1; i<=2000; i++)
    {
        mapfile[i] = 0;
    }
    

    In this code here, you see that you are requesting 2000 units of memory. In this case mmap is taking in a size_t type meaning that its looking for a size, and not an amount of things for memory. As @Mat mentioned, you will need t use the sizeof(int) operator in order to feed mmap the proper size it requires.

    The other issue that should be noted about this code that may cause a problem for you down the road, is beginning your loop index at i=1 rather than i=0. Starting your index at 0 wil ensure that you are going from the indices 0 - 1999, which corresponds to the memory you are trying to allocate.

    Overall here, it looks like what your trying to do is initialize the values of your memory to 0. perhaps you could do this easier by relying on a builtin function called memset:

    void *memset(void *str, int c, size_t n)
    

    your code then becomes:

    mapfile = mmap(NULL, 2000*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, ret, 0);
    void *returnedPointer = memset(mapfile, 0, 2000*sizeof(int));
    

    docs for memset can be found here: http://www.tutorialspoint.com/c_standard_library/c_function_memset.htm