Is madvise(*, *, MADV_DONTNEED)
supposed to be purely advisory? I tried scanning /proc/self/maps
and calling madvise(addr, size, MADV_DONTNEED)
on the entries:
#include <stdio.h>
#include <sys/mman.h>
int main(void) {
FILE *fp;
char line[1024];
fp = fopen("/proc/self/maps", "r");
if (fp == NULL) {
perror("Failed to open maps file");
return 1;
}
while (fgets(line, sizeof(line), fp)) {
char addr[32], perms[8], offset[32], dev[32], inode[32], path[256];
unsigned long start, end;
path[0] = '\0';
sscanf(line, "%lx-%lx %s %s %s %s %[^\n]", &start, &end, perms, offset, dev, inode, path);
int ret = madvise((void*)start, end - start, MADV_DONTNEED);
if(ret == 0)
printf(" OK\n");
else
printf(" Error\n");
fflush(stdout);
}
fclose(fp);
}
But this prints:
OK
OK
OK
OK
Segmentation fault
Is there a simple way to tell (from /proc/self/maps
, /proc/self/smaps
or otherwise) which memory segments a process is allowed to call madvise(*, *, MADV_DONTNEED)
on?
man 2 madvise
says:
These advice values do not influence the semantics of the application (except in the case of MADV_DONTNEED), but may influence its performance.
And:
After a successful MADV_DONTNEED operation, the semantics of memory access in the specified region are changed: subsequent accesses of pages in the range will succeed, but will result in either repopulating the memory contents from the up-to-date contents of the underlying mapped file (for shared file mappings, shared anonymous mappings, and shmem-based techniques such as System V shared memory segments) or zero-fill-on-demand pages for anonymous private mappings.
And man 3 posix_madvise
says:
the corresponding madvise(2) value, MADV_DONTNEED, has destructive semantics.
So no, it's not purely advisory, and yes, it can cause segfaults if you blindly do it everywhere.