【问题标题】:Set the heap start address in C program?在C程序中设置堆起始地址?
【发布时间】:2015-03-22 03:21:57
【问题描述】:

有没有办法在linux的GCC编译的C程序中设置堆起始地址?在 x86_64 系统中,我的测试程序将堆地址设置为 4 字节引用地址(小于 FFFFFFFF)。我想将此设置为 8 字节引用地址以进行某些测试(> FFFFFFFF)。 GCC 是否提供任何设置堆起始地址的方法?

【问题讨论】:

  • 请定义你的“堆起始地址”。大多数malloc-s 都在使用mmap(这取决于ASLR...)
  • 你为什么要问?你为什么在乎?
  • 我正在调试一个似乎在堆超过 4 个字节时发生的崩溃,我猜这可能是由于一些指向整数分配的指针而发生的。但是我的测试程序总是在 4 字节的可寻址空间中有堆。
  • 不能用链接器完成吗?
  • 使用valgrind

标签: c gcc elf heap-memory


【解决方案1】:

您可以使用sbrk() 间接地做到这一点:

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

int main(void)
{
  sbrk(0xFFFFFFFF);
  printf("%p\n", malloc(1));
  return 0;
}

这是通过在一开始就“分配”0xFFFFFFFF 字节来实现的,这样malloc() 可以分配的下一个地址是更高的地址。

【讨论】:

  • 可能并不总是有效,因为大多数malloc-s 正在使用越来越多的mmap。实际上,sbrk 甚至堆启动在今天并没有太多使用(特别是因为它不是多线程友好的)
  • @BasileStarynkevitch:使用sbrk() 将有效地保留从略高于零到超过 0xFFFFFFFF 的所有虚拟地址。所以 mmap() 与否, malloc() 将别无选择,只能按照 OP 的要求返回高地址。你有反例吗?我尝试将上面代码中的 malloc() 大小更改为几兆字节,使其使用 mmap(),但地址甚至更高,从未低于 0xFFFFFFFF。
  • @John Zwinck 好吧,它不会从地址 0 保留,它会从当前数据段开始的任何地方保留 - 可以有很多东西映射到低地址。从理论上讲,malloc 实现可以在映射中的某个地方找到一个漏洞来进行分配。
  • @nos:我不太清楚这将如何发生:malloc() 将调用 sbrk() 并且只能增长段,而不是“在映射中查找漏洞”。我已经准备好相信你是对的,从技术上讲它可能会以这种方式发生,我只是不明白如何......除非 mmap() 给出低地址,而在我见过的 64 位系统上没有似乎真的发生了。无论如何,似乎这个解决方案对 OP 来说已经足够好了,但很高兴能理解其中的细节。
猜你喜欢
  • 2020-01-02
  • 2015-09-23
  • 1970-01-01
  • 2011-01-22
  • 2021-10-02
  • 2011-01-04
  • 1970-01-01
  • 2018-08-15
  • 2013-05-16
相关资源
最近更新 更多