c - 在 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 内核在你自己的虚拟地址空间中指示一些空闲区域?
解决方案
你说:
理论上,您可以解析此文本并了解哪些虚拟地址是免费的。但是这个地图文件完整吗?有没有更惯用的方法让 Linux 内核在你自己的虚拟地址空间中指示一些空闲区域?
是的,在理论上和实践中,确实是 linux 采用的方法来为您提供有关您的进程映像的信息。你可以,而且你应该。
它应该是完整的,因为它的唯一目的(这需要内核中的代码以这种简单的格式为您提供此信息)是为您提供信息。
恐怕这是最好的了。您可以直接从它用来映射您的进程的内核表中获得数字......所以没有更好的信息可以猜测。其他区域(虚拟地址空间中未被占用的区域)不是空闲的。他们根本没有被分配,任何向他们推荐的审判都会导致您SIGSEGV
违反规定。这是一种保护机制,可让您检测到您在代码中做了一些令人讨厌的事情,这是操作系统可以为您提供的最大功能,因为一旦它为您提供内存,它的使用就是您的问题,没有什么可以阻止您的内存被使用你想要的方式。
嗯,我不知道这是否是你期望的那种答案,但没有别的,所以你必须通过它。在今天的代码中,读取/proc
文件并将 ascii 字符串转换为数字很便宜,因此您无需考虑更好的方法。只是scanf()
或fgets()
它,并转换。
我不清楚您为什么要在虚拟地址空间中要求免费区域(未分配)。为了让它们被占用,您需要执行一些操作系统调用,这需要一个通常接受的调用,允许内核决定什么是最好的使用位置(通常有一种方法可以让您指定提示,但因为通常有硬件放置位置的限制,遵守您使用的参数....或不遵守)
在当今的操作系统中,内核有很大的分配空间,分配给你一个内存区域的地方有问题,所以最好是让系统为你做,而不需要计算已经分配了什么。什么没有。
推荐阅读
- python - Tensorflow 1.10+:将纪元传递给估计器 input_fn?
- python - Python:如何将图像分割成块。然后加入原始图像
- python - 使用 python 和 postgresql 创建一个 dockerfile
- excel - 循环遍历数据集并停止并选择
- python - 绕过巨大的python列表和直方图的内存问题
- javascript - React componentDidUpdate 不会在 url 更改时更改 props.match.params?
- arrays - 如何显示带有索引的数组。我从 HTTP GET 请求中获取数组
- javascript - 停止将锚标记添加到当前 URL
- c# - 带有布尔谓词的动态 OrderBy 表达式
- docker - .dockerignore 无法在具有 !**/*.extension 模式的子目录中包含文件