Domanda

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;
}
È stato utile?

Soluzione

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

Altri suggerimenti

You're requesting 2000 bytes from mmap, but treating the returned value as an array of 2000 ints. That can't work, an int is usually 4 or 8 bytes these days. You'll be writing past the end of the reserved memory in your loop.

Change the mmap calls to use 2000*sizeof(int). And while you're at it, give that 2000 constant a name (e.g. const int num_elems = 2000; near the top) and don't repeat the magic constant all over the place. And once that's done change it to 1024 or 2048 so that the resulting size is a multiple of the page size (if you're not sure of your page size, getconf PAGE_SIZE on the command line).

And also change your dd command to create a large-enough file. It is currently creating a 2000 byte file, you'll need to increase that as well.

And validate the return value of mmap - it can fail, and you should detect that.

Finally, don't continuously remap, you're using MAP_SHARED modifications through other shared mappings of the same file and offset will be visible to your process. (Must really be the same file, if the other process also does a dd, that might not work. Only one process should have the responsibility of creating that file.)

If you do want to remap, you must also unmap each time. Otherwise you're leaking mappings.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top