Lucia
Lucia

Reputation: 371

Shared memory and memcpy issue

I'm learning to program with shared memory in C (linux). I need to share some struct among several process that will be created with fork(). Unfortunately, when i'm trying to initialize the newly shared address space i get a slient error (no output in console) at the memcpy call.

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

#define ROWS 10000
#define COLS 15000

struct mm_shared {
    int test;
    unsigned char matrix[ROWS][COLS];
};

int main(void) {

    int fd;
    if ((fd = shm_open("/mm", O_CREAT | O_RDWR, 0777)) == -1) {
        printf(stderr, "shm_open failed! %d - %s\n", errno, strerror(errno));
    }

    if (ftruncate(fd, sizeof(struct mm_shared) == -1)) {
        printf(stderr, "ftruncate failed! %d - %s\n", errno, strerror(errno));
    }

    struct mm_shared * shared;
    if ((shared = mmap(NULL, sizeof(struct mm_shared), PROT_READ
            | PROT_WRITE, MAP_SHARED, fd, 0)) == -1) {
        printf("mmap failed! %d, %s\n", errno, strerror(errno));
    }
    struct mm_shared * init = (struct mm_shared *) malloc(sizeof(struct mm_shared));

    memcpy(shared, init, sizeof(struct mm_shared)); <-- here lies the problem!


    shm_unlink("/mm");
    return EXIT_SUCCESS;
}

When debugging the shared pointer, the debug info (eclipse debugger) shows:

Failed to execute MI command:
-data-evaluate-expression (shared)->test
Error message from debugger back end:
Cannot access memory at address 0x7ffff7ffc000

I don't know if this may help. Also, i would like to ask if my approach of storing a big matrix inside the struct is right (it should be allocated in the heap right? because i get a pointer to the struct even when the matrix itself isn't a pointer).

Any help with this would be greatly appreciated!

Upvotes: 1

Views: 4620

Answers (1)

asio_guy
asio_guy

Reputation: 3767

After an hour of debugging and review cycles found the error finally, and its this

second argument for ftruncate seems to be evaluating to wrong value
if (ftruncate(fd, sizeof(struct mm_shared) == -1)) {

Changed to

if (ftruncate(fd, sizeof(struct mm_shared)) == -1) {

Here is code with alterations

int main(void) {

    int fd;
    if ((fd = shm_open("/mm", O_CREAT | O_RDWR, 0777)) == -1) {
        fprintf(stderr, "shm_open failed! %d - %s\n", errno, strerror(errno)); // should be fprintf
    exit(1);// possibly exit here
    }

    //if (ftruncate(fd, sizeof(struct mm_shared) == -1)) {
    if (ftruncate(fd, sizeof(struct mm_shared)) == -1) {
        fprintf(stderr, "ftruncate failed! %d - %s\n", errno, strerror(errno)); // should be fprintf
    goto out;   // remove all before leaving    
    }

    struct mm_shared * shared;
    if ((shared = mmap(NULL, sizeof(struct mm_shared) , PROT_READ
            | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED ) {  // Change -1 to MAP_FALED
        fprintf(stderr, "mmap failed! %d, %s\n", errno, strerror(errno)); // should be fprintf and stderr 
    goto out;   // remove all before leaving
    }
    struct mm_shared * init = (struct mm_shared *) malloc(sizeof(struct mm_shared));

    //memcpy(shared, init, sizeof(struct mm_shared)); //<-- here lies the problem!
    memcpy(init, shared, sizeof(struct mm_shared)); //<-- here lies the problem!

out:
    shm_unlink("/mm");
    return EXIT_SUCCESS;
}

Upvotes: 2

Related Questions