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

标签 c linux memory mmap system-calls

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

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

int is_mmapped(void *ptr, size_t length);

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

最佳答案

作为Ross Ridge在评论中建议,/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

正如预期的那样。

关于c - 如何检查内存区域是否映射到文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25704455/

相关文章:

php - 当使用 php exec() 运行 shell 脚本时,一个脚本可以工作(只执行 git status)而另一个不可用(执行 git checkout)。怎么会?

linux - 我可以使用本地脚本通过 SSH 连接到多个服务器(从本地到 servA,然后从 servA 到 servB)吗?

php - Apache PHP 命令不会控制 Raspberry pi GPIO

c# - 调用 Application.Exit() 后,应用程序仍在内存中运行

安卓内存测试

c - 没有 float 的有效计算方法,C

c - (C 语言) 有没有办法在 while 循环中放置两个不同的可能整数值的条件参数?

c - 为什么 FILE 指针在传递给函数后在 C 中返回 main 时会发生变化?

java - 为所有小程序设置默认内存限制

c - 从 Windows 内部修改 SMBIOS