Search code examples
cshared-memory

Modifying a value inside a shared memory is stopping the program


I am using a shared memory of an array of struct, this struct contains the code of different lobbies. Each lobby is a different fork (that's why the use of a shared memory), and are writing their own struct into the array. The parent fork should be able to see and access every code.

Initializing the shm

int fd = shm_open("tabLobby", O_CREAT | O_RDWR, S_IRWXU);  
    // Set the size of the shared memory object
    int pageSize = sysconf(_SC_PAGE_SIZE);
    CHECK(ftruncate(fd, pageSize), "__ftruncate__");
    // Map the tabEtats object into the virtual address space of the calling process
    tabLobby = mmap(0, pageSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

Forking, and retreiving data

int pidLobby;
            tabLobby[nbLobby].pidLobby = 0;
            CHECK(pidLobby = fork(), "fork()");
            if(pidLobby == 0) {
                // Child
                serveurLobby(nbLobby);
                exit(EXIT_SUCCESS);
            } else {
                // Father
                while(tabLobby[nbLobby].pidLobby == 0) {
                    sleep(1);
                }
                // Show code and port
                printf(GREEN "Création du Lobby %s (Port %d)\n" RESET, tabLobby[nbLobby].code, tabLobby[nbLobby].port);
                // Writing response data
                send_t sendData;
                sendData.args[0] = tabLobby[nbLobby].ip;
                sendData.args[1] = tabLobby[nbLobby].code;
                char* portChar = malloc(sizeof(char) * 5);
                sprintf(portChar, "%d", tabLobby[nbLobby].port);
                sendData.args[2] = portChar;
            }

The child fork

void serveurLobby(int idLobby) {
    // Emplacement du lobby dans le tableau
    tabLobby[idLobby].ip = ip;
    tabLobby[idLobby].port = port;
    char* code = malloc(sizeof(char) * 6);
    // This functions generates a random code and puts it into code
    generateLobbyCode(code);
    strcpy(tabLobby[idLobby].code, code);
    printf("Lobby code : %s\n", tabLobby[idLobby].code);
    tabLobby[idLobby].pidLobby = getpid();
}

Multiple things I saw:

  • When doing directly tabLobby[idLobby].code = "TEST", it works
  • When modifying the tabLobby[idLobby].code in any other way, the program just stops (no error or crash, just a plain old freeze)
    • This can be doing tabLobby[idLobby].code[0] = 'a', using strcpy, strdup...
  • When I do tabLobby[idLobby].code = code instead of using strcpy or else, the information is lost as soon as the function ends

Hope this description helps!


Solution

  • You can share a page a memory with other processes, but that doesn't mean anything else is shared. If you do a malloc, the memory allocated is not shared, so the other process will not be able to access it.

    Everything needs to be within the shared memory block. You might need to create some memory management tools so you can allocate and deallocate blocks of memory within the shared memory.

    Or, declare the code member as a fixed size array. Then, you can copy to it directly, but you will have to limit how much you copy.

    Sounds like you have code as a char *. Which means, if you try to copy to it (using code[0] or strcpy) you get undefined behavior (i.e. a crash or freeze most likely), because you probably haven't set the pointer to anything.

    If you set the pointer to "literal string" you are getting somewhat undefined behavior. The memory for the string might be shared, depending on the OS and compiler/linker, but most likely, that string will not be readable by the other process. using malloc, it definitely will not be able to read it.