如何解决如何在程序中找到 MMAPable 虚拟地址的范围?
背景信息:
-
我在 x86 系统上使用 64 位 Arch。
-
我没有使用 libc 或任何依赖于 libc 的语言。我正在使用专有的研究语言。我正在通过内联汇编进行系统调用。
根据这篇 SO 帖子:Where is the stack memory allocated from for a Linux process? 程序的虚拟地址空间的组织方式如下:
------------------ <--- Top of the process address space
Stack (grows down)
v v v v v v v v v
------------------
(unmapped)
------------------ <--- Maximum stack size.
(unmapped)
-------------------
mmap
-------------------
(unmapped)
-------------------
^ ^ ^ ^ ^ ^ ^ ^ ^ ^
brk (grows up)
-------------------
BSS
-------------------
Data
-------------------
Text
-------------------
------------------- <--- Bottom or process address space.
假设这是正确的,我正在尝试找到 brk 和堆栈之间的 MMAPable 地址范围。
通过从 sbrk(0)
获取 ptr,页面向上对齐 ptr,然后确保永远不会再次调用 brk
和 sbrk
来找到下限是否足够?
通过将 ptr 移到堆栈上的某个位置、从 getrlimit
获取堆栈的最大大小、从 ptr 中减去该大小、将 ptr 向下对齐页面以及然后确保堆栈的大小永远不会被setrlimit
改变?
我在这里不需要一个确切的范围,但我确实需要一个大范围的连续地址,这些地址可以保证是安全的 MMAPable(当然,假设我自己不会破坏它们)。在我的研究中,我遇到了这个: https://www.ibm.com/docs/en/aix/7.2?topic=memory-understanding-mapping ,它说:
对于 64 位进程,有两组地址范围和进程地址空间可用于 mmap 或 shmat 映射。第一个由单个范围 0x07000000_00000000-0x07FFFFFF_FFFFFFFF 组成,可用于固定位置和可变位置映射。第二组地址范围仅适用于固定位置映射,包括范围 0x30000000-0xCFFFFFFF、0xE0000000-0xEFFFFFFF 和 0x10_00000000-0x06FFFFFF_FFFFFFFF。该集合的最后一个范围由 0x10_00000000-0x06FFFFFF_FFFFFFFF 组成,也可用于系统加载程序以保存程序文本、数据和堆,因此只有该范围的未使用部分可用于固定位置映射。
这正是我需要的信息类型,但它用于错误的操作系统。如果有人能帮我找到有关 Linux 的相同信息,特别是 Arch,那将是一个很大的帮助。
解决方法
经过大量测试后,我发现我在问题中提出的解决方案确实有效。我一直在使用 cat /proc/<pid>/maps
检查我的自定义分配器,它的行为符合我的预期。重申解决方案:
-
要找到下限,请使用
sbrk(0)
,确保 ptr 页面对齐,然后确保永远不会再次调用brk
和sbrk
。 -
为了安全地逼近上限,使用
getrlimit
找到堆栈大小,从 ptr 中减去它进入堆栈,页面对齐 ptr,然后永远不要使用setrlimit
更改堆栈大小.
如果您可能需要触摸 brk
、sbrk
或 setrlimit
,那么您还可以在下限中添加一些填充并从上限中减去一些填充。您可以通过使用 /proc/meminfo
查找系统有多少内存来动态计算安全的填充量,或者如果您不需要通用解决方案,您可以根据您的情况过度估计需要多少正在做。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。