fakedrake
fakedrake

Reputation: 6856

Shared memory with mmap returns when writing to mapped memory on linux

I was trying to figure out shared memory and tried to write a simple program involving a consumer and a producer. I didnt make it to the consumer part and found this weird little problem: The parent will return at the *spool=3; with no rhyme or reason on why. Nothing on dmesg.

#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#define PRODUCER_ERROR(msg)         \
    do {perror("Producer Error: " msg "\n"); exit(1); }while(0)

#define SHM_NAME "/my_sharedmem"

void producer();

int main(int argc, char *argv[])
{
    pid_t pID = fork();
    if (pID == 0) {
    // Code only executed by child process
    printf ("Son here\n");
    return 0;
    } else if (pID < 0) {
    perror("Unable to fork\n");
    exit(1);
    } else {
    // Code only executed by parent process
    printf ("Parent here\n");
        producer();
    return 0;
    }

    return 0;
}


void producer()
{
    int fd, d;
    unsigned* spool;

    printf("<<Producer>> started\n");
    fd = shm_open(SHM_NAME, O_CREAT | O_RDWR,  S_IRWXU | S_IRWXG | S_IRWXO ); // FIXED

    printf ("<<Producer>> memory file opened\n");

    spool = mmap(NULL, sizeof(unsigned), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0);
    printf ("<<Producer>> mmaped to %p\n\tGonna write.\n", spool);
    perror(NULL);

    *spool = 3;
    // msync(spool, sizeof(unsigned), MS_SYNC | MS_INVALIDATE);

    printf("<<Producer>> ended\n");
}

EDIT: fixed shm_open mode argument

Upvotes: 1

Views: 1339

Answers (2)

Jens Gustedt
Jens Gustedt

Reputation: 78903

You have the mode argument to shm_open wrong. This is supposed to be a mode specification as for open. Probably your version here by conincidence forbids writing to the address, so the process then crashes when you try to write to it.

BTW: you should always check the return of library calls such as shm_open and mmap.

Edit: As I also observed in a comment below, you are also missing to scale the segment to an appropriate size with ftruncate.

Upvotes: 1

Art
Art

Reputation: 20392

The object you get with shm_open is zero size. You need to allocate some space for it. mmap will allow you to map things beyond their size (both shm objects and files), but you'll crash when you access that memory.

Something like this after shm_open is what you want to do:

ftruncate(fd, <the size you want>);

You can do it after mmap too, if that floats your boat.

Upvotes: 3

Related Questions