Reputation: 371
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
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