madvise(addr, size, MADV_DONTNEED) 会导致段错误吗?

问题描述 投票:0回答:1

madvise(*, *, MADV_DONTNEED)
应该纯粹是建议性的吗?我尝试扫描
/proc/self/maps
并致电
madvise(addr, size, MADV_DONTNEED)

#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);
}

但是这会打印:

  OK
  OK
  OK
  OK
Segmentation fault

有没有一种简单的方法来告诉(从

/proc/self/maps
/proc/self/smaps
或其他方式)进程允许在哪些内存段上调用
madvise(*, *, MADV_DONTNEED)

c linux memory system-calls
1个回答
0
投票

man 2 madvise
说:

这些建议值不会影响应用程序的语义(MADV_DONTNEED 情况除外),但可能会影响其性能。

并且:

MADV_DONTNEED 操作成功后,指定区域中的内存访问语义将发生更改:该范围内页面的后续访问将成功,但会导致从底层映射的最新内容重新填充内存内容文件(用于共享文件映射、共享匿名映射和基于 shmem 的技术,例如 System V 共享内存段)或用于匿名私有映射的按需零填充页面。

并且

man 3 posix_madvise
说:

相应的 madvise(2) 值 MADV_DONTNEED 具有破坏性语义。

所以不,这不是纯粹的建议,是的,如果你到处盲目这样做,它可能会导致段错误。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.