如何检查内存区域是否映射到文件?

时间:2014-09-06 20:28:10

标签: c linux memory mmap system-calls

有没有办法检查内存区域是否使用mmap映射到某个基础文件?

我的意思是我想写一个函数:

int is_mmapped(void *ptr, size_t length);

使用mmap系统调用返回完全映射到文件的内存区域的非零值。

1 个答案:

答案 0 :(得分:2)

在评论中提到MovieClip时,/proc/self/maps可以为您提供帮助。

每一行看起来像这样:

35b1a1f000-35b1a20000 r--p 0001f000 08:02 135522  /usr/lib64/ld-2.15.so
START ADDR- END ADDR  PERM  OFFSET   DEV   INODE   PATHNAME

我们关心的只是起始地址和结束地址,所以这不需要太多代码:

#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int is_mmaped(void *ptr, size_t length) {
    FILE *file = fopen("/proc/self/maps", "r");
    char line[1024];
    int result = 0;
    while (!feof(file)) {
        if (fgets(line, sizeof(line) / sizeof(char), file) == NULL) {
            break;
        }
        unsigned long start, end;
        if (sscanf(line, "%lx-%lx", &start, &end) != 2) {
            continue; // could not parse. fail gracefully and try again on the next line.
        }
        unsigned long ptri = (long) ptr;
        if (ptri >= start && ptri + length <= end) {
            result = 1;
            break;
        }
    }
    fclose(file);
    return result;
}

还有一些测试:

int main(int argc, char *argv[]) {
    void *test = mmap(NULL, 16384, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    printf("T %d\n", is_mmaped(test, 16384));
    printf("F %d\n", is_mmaped(test, 16385));
    printf("F %d\n", is_mmaped(test + 1, 16384));
    printf("T %d\n", is_mmaped(test, 1024));
    printf("T %d\n", is_mmaped(test, 256));
    printf("T %d\n", is_mmaped(test, 8));
    printf("T %d\n", is_mmaped(test + 16383, 1));
    munmap(test, 16384);
    printf("F %d\n", is_mmaped(test, 16384));

    printf("T %d\n", is_mmaped(main, 32));
    return 0;
}

打印:

T 1
F 0
F 0
T 1
T 1
T 1
T 1
F 0
T 1

正如所料。