-1

I'm using shared_memory using POSIX..

I've allocated 4KB, but i can use a lot more than 4KB... it gives me a segmentation fault when i write more than ~10350 characters into memory. which equals to ~10350 byte / 1024 = ~10KB ?

I believe that the operating system should guard the Memory for such a violation, but it allows me to ? Why ?

Producer Source-code which is used to put something into the shared-memory segment

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main(void)
{
const int size = 4096; //4kb
const char *name = "os";
const char *message = "Put more than 5000 chars it will work perfectly but less than 10350 or something like that";
int shm_fd;
void *ptr;
shm_fd = shm_open(name,O_CREAT | O_RDWR,0666);
ftruncate(shm_fd,size);// set the size to 4kb
ptr = mmap(0,size,PROT_WRITE | PROT_READ,MAP_SHARED,shm_fd,0);
sprintf(ptr,"%s",message);
ptr += strlen(message);
return 0;
Mohamed Horani
  • 544
  • 3
  • 9
  • 23
  • 4
    If your question is "why can I write beyond the bounds of the memory I allocated?", then the answer is "undefined behaviour". – Oliver Charlesworth Nov 08 '15 at 18:36
  • Are you asking for a run time environment that manages memory for you and doesn't let you use unauthorized memory? Other languages do that, not C. C lets you shoot yourself in the foot. – R Sahu Nov 08 '15 at 18:40
  • 1
    undefined behaviour! it didn't answer my question.. i need to know why this undefined behaviour happens ? – Mohamed Horani Nov 08 '15 at 18:40
  • If you do not play by the rules then expect anything. – Ed Heal Nov 08 '15 at 18:41
  • what rules are you talking about ? – Mohamed Horani Nov 08 '15 at 18:42
  • Where is the code that writes above 4k – Ed Heal Nov 08 '15 at 18:43
  • ill update my post soon – Mohamed Horani Nov 08 '15 at 18:44
  • There is you problem. Ask for 4k - trying extra. That is not withing the rules – Ed Heal Nov 08 '15 at 18:46
  • I've updated the source code... but the consumer code, the one that reads and delete the shared memory is not required for my case.. – Mohamed Horani Nov 08 '15 at 18:51
  • It shouldn't give you segfaults even if you wrote 10GiB. On Linux `shm_open` creates normal files on a RAM-mounted filesystem. Normal files generally can grow pretty much without limits. – Petr Skocik Nov 08 '15 at 18:53
  • Now if you `mmap` it, that's a different matter. But why would you mmap a file that's on a RAM disk? You should use either shm_open or mmap (against no physical file), not both. – Petr Skocik Nov 08 '15 at 18:55
  • What do you get when you execute `getconf PAGE_SIZE`? – Petr Skocik Nov 08 '15 at 18:58
  • getpagesize() --> 4kb i'm using linux under virtual machine – Mohamed Horani Nov 08 '15 at 19:00
  • 1
    I'm voting to close this question as off-topic because UB #016598235 – Martin James Nov 08 '15 at 19:04
  • 1
    u closing this question because UB #016598235 ? why ? & what that suppose to mean ? – Mohamed Horani Nov 08 '15 at 19:05
  • You may believe what you like about what the o/s should do, but the o/s does what it does and you can't readily change it. You will find it easier to change your beliefs to reflect reality than to make reality reflect what you believe. Either way, when you try to access memory you didn't allocate, you invoke _undefined behaviour_. That means that anything can happen, from complete reformatting of your machine's hard drive to "it works". Most often, when you abuse memory, you end up with corrupted data structures or crashes . But don't risk undefined behaviour — you don't know what will happen. – Jonathan Leffler Nov 08 '15 at 19:22

1 Answers1

1

My system has 4KiB pages sizes too, and my default stack size is 8KiB. If I do:

#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
int main(){
  const int size = 4096;
  const char *name = "os";
  int shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
  ftruncate(shm_fd,size);// set the size to 4kb
  char* ptr = (char*)mmap(0,size,PROT_WRITE | PROT_READ,MAP_SHARED,shm_fd,0);
  for(int i=0; i>=0; i++){
    printf("%d\n", i);
    ptr[i]='x';
  }
  return 0;
}

It'll deterministically segfault at 12KiB (12288). I think it mmaps at the beginnig of your heap space, that is right next to the stack (8KiB) and overflowing the 4KiB leads to trashing the stack space, after which it segfaults.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142