简体   繁体   中英

Reading From Shared Memory Using mmap - Segmentation Fault

I'm still trying to wrap my head around shared memory. What I'm trying to accomplish is to have an array of pods. Each pod will also contain an array of keyValue.

typedef struct {
   char key[256];
   char value[256];
}keyValue;

typedef struct {
   keyValue **arr;
   int count;
}pod;

int fd;

int main(int argc, char **argv) {
   int kv_store_create(char *name) {
       return shm_open(name, O_CREAT|O_RDWR, S_IRWXU);
   }

   void kv_store_write(char *key1, char *value1) {

      static pod (*str)[28];

      ftruncate(fd, sizeof(str));

      str = (pod(*)[28])mmap(NULL, sizeof(str), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

      for (int i = 0; i < 28; i++) {
         str[i]->arr = (keyValue **)malloc(28 * sizeof(keyValue));
         for(int j = 0; j < 28; j++) {
            str[i]->arr[j] = (keyValue *)malloc(256 * sizeof(keyValue));
         }
       }

       strncpy(str[0]->arr[0]->key, key1, strlen(key1));
       strncpy(str[0]->arr[0]->value, value1, strlen(value1));
       str[0]->count = 1;
    }

   fd = kv_store_create("sharedmem");

   kv_store_write("key", "value");

So at this point, I have a keyValue in a pod, and if I read the shared memory from the same file, I have no issues.

The issue arises when I try to read from another process. I have the following file

int main(int argc, char **argv) {

    typedef struct {
        char key[256];
        char value[256];
    }keyValue;

    typedef struct {
        keyValue **arr;
        int count;
    }pod;


    int fd = shm_open("sharedmem", O_RDWR, 0);
    if (fd < 0) {
        printf("Error... opening shm\n");
    }

    struct stat s;

    if (fstat(fd, &s) == -1) {
        printf("Error fstat\n");
    }

    pod (*str2)[28];

    str2 = (pod(*)[28])mmap(NULL, s.st_size, PROT_READ, MAP_SHARED, fd, 0);

    printf("%s", str2[0]->arr[0]->key); 

}

The printf is causing a seg fault and I believe it is trying to access part of a memory that has nothing allocated, while that printf would actually print in my first file.

I'm trying to figure out why is spitting out an error and what route should I take to be able to share an array of structs between two processes

Thanks!

What you say is:

Each pod will also contain an array of keyValue.

But that's not the case, because a pod is:

typedef struct {
   keyValue **arr;
   int count;
}pod;

which doesn't contain an array of KeyValue . It contains a pointer to an array of KeyValue* , but the KeyValue objects themselves are neither in the pod nor in the memory pointed to by arr . So they definitely are not in the memory you are sharing between the two processes.

So the reading process gets a pod which contains a pointer to an address in the owning process ; obviously, that pointer is completely meaningless in the reader since processes do not share memory so having an address of an object in another process is more or less equivalent to having a random number.

In short, you have to make sure the shared memory region actually contains all of the objects you want to share, not just pointers to them. And since it is unlikely that mmap will return the same address in the two processes, it will not be useful to insert pointers in the shared memory even to objects which are placed in the shared memory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM