1

i have few question based on below source:

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

int g;
int main(void) {
    int fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(fd, sizeof(int)); // set size by sizeof(int)
    int *p1 = mmap(NULL, 10*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0); //now map  10*sizeof(int).
    if (p1== MAP_FAILED) {
        printf("*****************error");
    }
    *p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);
    if (p1== MAP_FAILED) {
        printf("*****************error");
    }

    *p1=89;

    return g;
}

Question 1 : why i don't see any error while i set size as size_of(int) and then map 10*size_of(int)

Question 2: how many instace of shared mem is created here? i mean is there only one shared mem created or two as i did mmap twice?

Thanks

Eric Ipsum
  • 723
  • 3
  • 10
  • 24

1 Answers1

1

Given the code

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

int g;
int main(void) {
    int fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(fd, sizeof(int)); // set size by sizeof(int)
    int *p1 = mmap(NULL, 10*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0); //now map  10*sizeof(int).
    *p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);
    if (!p1){
        printf("*****************error");
    }
    *p1 = g;
    *p1=89;

    return g;
}

Question 1 : why i don't see any error while i set size as size_of(int) and then map 10*size_of(int)

Because you don't check the return value from mmap(), you don't know if an error happened or not. By immediately calling mmap() again with

*p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);

you mask any potential errors from the first mmap() call, and you also leak any memory that was successfully allocated.

Question 2: how many instace of shared mem is created here? i mean is there only one shared mem created or two as i did mmap twice?

If the first call succeeded, you mapped two memory segments. If it failed, you only mapped one if the second once succeeded.

If the first call did succeed, you leaked the memory.

Note that if you tried to write to the mmap()'d segment past the end of the size of the file you set with ftruncate(), you will not cause the file to grow. Per the POSIX mmap() documentation:

Note that references beyond the end of the object do not extend the object as the new end cannot be determined precisely by most virtual memory hardware. Instead, the size can be directly manipulated by ftruncate().

On Linux, trying to access mmap()'d data beyond the end of the mapped file will likely result in your process receiving a SIGBUS signal.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • actually it does not shows any error if i use if (p1== MAP_FAILED) { printf("*****************error"); } after the first mmap also. – Eric Ipsum Mar 01 '19 at 10:51
  • @EricIpsum If you change the code to detect failure and the check doesn't detect a failure, then the first `mmap()` worked. But as originally posted, you didn't really know if the first `mmap()` call worked or not, although it most likely did. – Andrew Henle Mar 01 '19 at 10:52