如何以编程方式获得在Linux上堆的地址 [英] How to programmatically get the address of the heap on Linux

查看:305
本文介绍了如何以编程方式获得在Linux上堆的地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以用 SBRK得到堆结束的地址(0),但有什么办法编程方式获得堆的起始地址,不是通过解析的/ proc /自/图

I can get the address of the end of the heap with sbrk(0), but is there any way to programmatically get the address of the start of the heap, other than by parsing the contents of /proc/self/maps?

推荐答案

我觉得解析的/ proc /自/图是在Linux的唯一可靠的方式找到堆段。而且不要忘了,有些分配器(包括一个在我的SLES)不要使用大块的mmap()这样的记忆是不是堆的一部分了,并且可以在任何随机位置。

I think parsing /proc/self/maps is the only reliable way on the Linux to find the heap segment. And do not forget that some allocators (including one in my SLES) do use for large blocks mmap() thus the memory isn't part of the heap anymore and can be at any random location.

否则,通常 LD 补充这标志着小精灵所有段的最后一个符号和符号被称为 _end 。例如:

Otherwise, normally ld adds a symbol which marks the end of all segments in elf and the symbol is called _end. E.g.:

extern void *_end;
printf( "%p\n", &_end );

的.bss ,传统上的最后一个精灵段的结束相匹配。该地址后,随着一些调整,通常遵循堆。堆栈(S)和mmap()的S(包括共享库)是在地址空间的更高的地址。

It matches the end of the .bss, traditionally the last segment of elf. After the address, with some alignment, normally follows the heap. Stack(s) and mmap()s (including the shared libraries) are at the higher addresses of the address space.

我不知道它是多么便携,但显然它的工作原理上的Solaris 10在HP-UX同样的方式11地图看起来不同,堆似乎与数据段合并,但不分配发生后的 _end 。在AIX上, procmap的不显示堆/数据段在所有,但分配也得到地址过去 _end 符号。因此,它似乎是的目前的携带十分方便。

I'm not sure how portable it is, but apparently it works same way on the Solaris 10. On HP-UX 11 the map looks different and heap appears to be merged with data segment, but allocations do happen after the _end. On AIX, procmap doesn't show heap/data segment at all, but allocations too get the addresses past the _end symbol. So it seems to be at the moment quite portable.

不过,都被认为是,我不知道怎么用就是。

Though, all considered, I'm not sure how useful that is.

P.S。测试程序:

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

char *ppp1 = "hello world";
char ppp0[] = "hello world";
extern void *_end; /* any type would do, only its address is important */

int main()
{
    void *p = calloc(10000,1);
    printf( "end:%p heap:%p rodata:%p data:%p\n", &_end, p, ppp1, ppp0 );
    sleep(10000); /* sleep to give chance to look at the process memory map */
    return 0;
}

这篇关于如何以编程方式获得在Linux上堆的地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆