tags:

views:

123

answers:

1

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?

+2  A: 

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.

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 );

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.

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. The test program:

#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;
}
Dummy00001