首页 > 解决方案 > 在 Linux 进程的地址空间中查找空闲区域

问题描述

从 Linux 进程内部,可以读取/proc/self/maps以查看其地址空间的描述。例如,

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

void print_maps() {
    int fd = open("/proc/self/maps", O_RDONLY);
    char buf[512];
    int rc;
    fflush(stdout); //Not necessary for this example, but I usually
                    //include before directly writing to STDOUT_FILENO
    while ((rc = read(fd, buf, sizeof(buf))) > 0) {
        write(STDOUT_FILENO, buf, rc);
    }
    close(fd);
}

int main(void) {

    print_maps();
    return 0;
}

对我来说,这个打印(我在 repl.it 上运行):

559de76b2000-559de76b3000 r-xp 00000000 00:12bf 411                      /home/runner/crt/main
559de78b2000-559de78b3000 r--p 00000000 00:12bf 411                      /home/runner/crt/main
559de78b3000-559de78b4000 rw-p 00001000 00:12bf 411                      /home/runner/crt/main
7f259008a000-7f2590271000 r-xp 00000000 08:01 4133143                    /lib/x86_64-linux-gnu/libc-2.27.so
7f2590271000-7f2590471000 ---p 001e7000 08:01 4133143                    /lib/x86_64-linux-gnu/libc-2.27.so
7f2590471000-7f2590475000 r--p 001e7000 08:01 4133143                    /lib/x86_64-linux-gnu/libc-2.27.so
7f2590475000-7f2590477000 rw-p 001eb000 08:01 4133143                    /lib/x86_64-linux-gnu/libc-2.27.so
7f2590477000-7f259047b000 rw-p 00000000 00:00 0 
7f259047b000-7f25904a4000 r-xp 00000000 08:01 4133125                    /lib/x86_64-linux-gnu/ld-2.27.so
7f25906a2000-7f25906a4000 rw-p 00000000 00:00 0 
7f25906a4000-7f25906a5000 r--p 00029000 08:01 4133125                    /lib/x86_64-linux-gnu/ld-2.27.so
7f25906a5000-7f25906a6000 rw-p 0002a000 08:01 4133125                    /lib/x86_64-linux-gnu/ld-2.27.so
7f25906a6000-7f25906a7000 rw-p 00000000 00:00 0 
7ffc92553000-7ffc92574000 rw-p 00000000 00:00 0                          [stack]
7ffc925f4000-7ffc925f7000 r--p 00000000 00:00 0                          [vvar]
7ffc925f7000-7ffc925f8000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

理论上,您可以解析此文本并了解哪些虚拟地址是免费的。但是这个地图文件完整吗?有没有更惯用的方法让 Linux 内核在你自己的虚拟地址空间中指示一些空闲区域?

标签: clinuxmmapvirtual-memory

解决方案


你说:

理论上,您可以解析此文本并了解哪些虚拟地址是免费的。但是这个地图文件完整吗?有没有更惯用的方法让 Linux 内核在你自己的虚拟地址空间中指示一些空闲区域?

是的,在理论上和实践中,确实是 linux 采用的方法来为您提供有关您的进程映像的信息。你可以,而且你应该。

它应该是完整的,因为它的唯一目的(这需要内核中的代码以这种简单的格式为您提供此信息)是为您提供信息。

恐怕这是最好的了。您可以直接从它用来映射您的进程的内核表中获得数字......所以没有更好的信息可以猜测。其他区域(虚拟地址空间中未被占用的区域)不是空闲的。他们根本没有被分配,任何向他们推荐的审判都会导致您SIGSEGV违反规定。这是一种保护机制,可让您检测到您在代码中做了一些令人讨厌的事情,这是操作系统可以为您提供的最大功能,因为一旦它为您提供内存,它的使用就是您的问题,没有什么可以阻止您的内存被使用你想要的方式。

嗯,我不知道这是否是你期望的那种答案,但没有别的,所以你必须通过它。在今天的代码中,读取/proc文件并将 ascii 字符串转换为数字很便宜,因此您无需考虑更好的方法。只是scanf()fgets()它,并转换。

我不清楚您为什么要在虚拟地址空间中要求免费区域(未分配)。为了让它们被占用,您需要执行一些操作系统调用,这需要一个通常接受的调用,允许内核决定什么是最好的使用位置(通常有一种方法可以让您指定提示,但因为通常有硬件放置位置的限制,遵守您使用的参数....或不遵守)

在当今的操作系统中,内核有很大的分配空间,分配给你一个内存区域的地方有问题,所以最好是让系统为你做,而不需要计算已经分配了什么。什么没有。


推荐阅读