简体   繁体   中英

Why does this code give a segfault? Shared memory IPC SYSV

Why does this code give a segfault? Shared memory IPC SYSV.

int * addr;
int shmid = shmget(0xABC, 10*sizeof(int), IPC_CREAT);

addr = (int*) shmat(shmid, NULL, 0);

for(i = 0; i < 10; ++i){
    addr[i] = (int)i*i;
}

shmdt(addr);

segfault

shmat() returns (void *) -1 on error.

Your code does not test for this. So if shmget() failed the code would try to dereference (void *) -1 here:

addr[0] = ...

which most certainly would invoke undefined behaviour.

shmat() might have failed as the code misses to specify access right to the memory segment requested by the call to shmget() .

As you want to write to it form the owning process the suitable rights to specify are

S_IWUSR 00200 user has write permission

(see man 2 open fo a full ist o access rights which might be set for the memeory segment request by shmget() )


As a general advice: Always test relevant system call for their outcome. Consider all such system calls as "relevant" which return a value that might be undefined or unusable in case the system call failed.

To do so in the particular case of the code shown, you migh modify the code like this:

  int shmid = shmget(0xABC, 10*sizeof(int), IPC_CREAT | S_IWUSR);
  if (-1 == shmid)
  {
    perror("shmget() failed");
    return EXIT_FAILURE;
  }

  int * addr = (int*) shmat(shmid, NULL, 0);
  if (((void *) -1) == addr)
  {
    perror("shmat() failed");
    return EXIT_FAILURE;
  }

  for(size_t i = 0; i < 10; ++i) 
  {
    addr[i] = (int)i*i;
  }

  if (-1 == shmdt(addr))
  {
    perror("shmdt() failed");
    return EXIT_FAILURE;
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM