代码之家  ›  专栏  ›  技术社区  ›  MWB

madvise(地址、大小、MADV_DONTNEDE)会导致分段故障吗?

  •  0
  • MWB  · 技术社区  · 5 月前

    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_DONTNEDE) 在?

    1 回复  |  直到 5 月前
        1
  •  2
  •   Joseph Sible-Reinstate Monica    5 月前

    man 2 madvise 说:

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

    以及:

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

    还有 man 3 posix_madvise 说:

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

    所以不,这不是纯粹的建议,是的,如果你盲目地在任何地方都这样做,它可能会导致分段错误。