Skip to content

Instantly share code, notes, and snippets.

@jmoiron
Created April 2, 2015 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmoiron/ec5329d099dfcf9ce5e7 to your computer and use it in GitHub Desktop.
Save jmoiron/ec5329d099dfcf9ce5e7 to your computer and use it in GitHub Desktop.
if you mmap an shm_open created fd, then ftruncate+mmap again, do you lose the memory you've been writing to?
#include <stdbool.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
void print_region(char *ptr, size_t len);
// mark a few locations in a pointer
void mark(char *ptr, size_t len) {
int i;
// do not mark position 0
for (i=1; i<len; i++) {
if (!(i%17)) {
ptr[i] = 1;
}
if (!(i%23)) {
ptr[i] = 2;
}
}
}
// check for the marks from mark
bool check(char *ptr, size_t len) {
int i;
for (i=1; i<len; i++) {
if (!(i%17) && (i%23)) {
if (ptr[i] != 1) {
return false;
}
} else if (!(i%23)) {
if (ptr[i] != 2) {
return false;
}
} else if (ptr[i] != 0) {
return false;
}
}
return true;
}
int main(int argc, char **argv) {
int i;
int fd, ok, max;
char *ptr;
shm_unlink("/test");
// create new shm
fd = shm_open("/test", O_CREAT|O_RDWR|O_TRUNC, 0);
if (fd < 0) {
perror("could not create shm_open fd");
return;
}
// make shm 1k
ok = ftruncate(fd, 1024);
if (ok < 0) {
perror("initial ftruncate");
goto done;
}
ptr = (char *)mmap(NULL, 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
printf("fd: %d\n", fd);
perror("map failed");
goto done;
}
mark(ptr, 1024);
if (!check(ptr, 1024)) {
printf("region failed check");
goto done;
}
max = 1024*1024;
printf("checking from size=1024 to size=%d\n", max);
for (i=2; i<=max/1024; i*=2) {
int size=1024*i;
ok = ftruncate(fd, size);
if (ok < 0) {
perror("second ftruncate");
goto done;
}
ptr = (char *)mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (!check(ptr, size/2)) {
printf("region failed check; mmap overwrote?");
goto done;
}
if (check(ptr, size)) {
printf("newly mapped region unexpectedly passed check");
goto done;
}
mark(ptr, size);
if (!check(ptr, size)) {
printf("region failed check");
goto done;
}
}
done:
shm_unlink("/test");
}
@reed-lau
Copy link

then what‘s the concluson under linux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment