Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

missing [heap] section in /proc/pid/maps

Tags:

c

memory

I'm experimenting with a simple C program that keeps allocating memory:

for ( i = 0; i < 10000; i ++ )
{
    array[i] = malloc( 1024*1024 );
    if ( array[i] == NULL )
    {
        break;
    }
    printf("Sleeping...%d\n", i);
    sleep( 60 );
}

Full code pasted here: http://tny.cz/2d9cb3df

However, when I cat /proc/pid/maps, I get no [heap] section. Why?

08048000-08049000 r-xp 00000000 08:11 17         /data/a.out
08049000-0804a000 r--p 00000000 08:11 17         /data/a.out
0804a000-0804b000 rw-p 00001000 08:11 17         /data/a.out
0804b000-0805e000 rw-p 00000000 00:00 0 
b74c6000-b75c8000 rw-p 00000000 00:00 0 
b75c8000-b7775000 r-xp 00000000 08:01 3539272    /lib/i386-linux-gnu/libc-2.17.so
b7775000-b7777000 r--p 001ad000 08:01 3539272    /lib/i386-linux-gnu/libc-2.17.so
b7777000-b7778000 rw-p 001af000 08:01 3539272    /lib/i386-linux-gnu/libc-2.17.so
b7778000-b777b000 rw-p 00000000 00:00 0 
b7797000-b779a000 rw-p 00000000 00:00 0 
b779a000-b779b000 r-xp 00000000 00:00 0          [vdso]
b779b000-b77bb000 r-xp 00000000 08:01 3539289    /lib/i386-linux-gnu/ld-2.17.so
b77bb000-b77bc000 r--p 0001f000 08:01 3539289    /lib/i386-linux-gnu/ld-2.17.so
b77bc000-b77bd000 rw-p 00020000 08:01 3539289    /lib/i386-linux-gnu/ld-2.17.so
bff21000-bff42000 rw-p 00000000 00:00 0          [stack]
like image 572
lang2 Avatar asked Jul 22 '13 07:07

lang2


People also ask

What does Proc PID maps contain?

The /proc/[pid]/mem file and Virtual Memory In short, the /proc/[pid]/maps file provides us the address; the /proc/[pid]/mem provides an interface into the memory space holding our data.

What is Proc PID Cmdline?

In linux, /proc includes a directory for each running process, including kernel processes, in directories named /proc/PID, these are the directories present: directory. description. /proc/PID/cmdline. Command line arguments.

What is Proc Statm?

/proc/[pid]/statm Provides information about memory usage, measured in pages.

What is proc self exe?

Function proc_self::exe[−][src]Returns a File of the currently running executable. Akin to fd::File::open("/proc/self/exe") on Linux.


2 Answers

Since you're talking about /proc/pid/maps I assume you're on linux.

This is what man malloc tells me on the linux distribution I happen to run:

Normally, malloc() allocates memory from the heap, and adjusts the size of the heap as required, using sbrk(2).

When allocating blocks of memory larger than MMAP_THRESHOLD bytes, the glibc malloc() implementation allocates the memory as a private anonymous mapping using mmap(2). MMAP_THRESHOLD is 128 kB by default, but is adjustable using mallopt(3).

Allocations performed using mmap(2) are unaffected by the RLIMIT_DATA resource limit (see getrlimit(2)).

If you really want to see [heap] in your /proc/pid/maps allocate less than 128k per call to malloc.

like image 71
Art Avatar answered Sep 27 '22 23:09

Art


The said section is just not declared as "heap", as it is allocated via mmap() calls.

Here on my 64 bit system, the memory allocated comes from this constantly growing section:

7f7fbda7a000-7f7fbdc7c000 rw-p 00000000 00:00 0
...
7f7fbc868000-7f7fbdc7c000 rw-p 00000000 00:00 0
...
7f7fbc363000-7f7fbdc7c000 rw-p 00000000 00:00 0

The section is extended at the start and the newly allocated memory always ias the start address + 0x10.

What the memory allocator does here is

mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7fbb353000

Strange thing; I would have suspected that every mmap()ed memory section is shown separately. But if I have the program do intermediate free() calls, the memory allocation follows this:

7f16be944000-7f16bec47000 rw-p 00000000 00:00 0
7f16bed48000-7f16bee49000 rw-p 00000000 00:00 0

There has been made a hole in the otherwise contiguous memory.

And an additional thing happens: in this modified program, there is indeed a [heap] section. Due to reasuns beyond my understanding, the program swithces over to allocating via brk(), and this is (probably) where the heap comes from:

with every brk() call, the respective section is extended at its end:

01183000-029a4000 rw-p 00000000 00:00 0                                  [heap]

I do not know what has changed malloc()'s mind to take the "real" heap (the stuff connected to brk()) for the allocations. The first munmap() call, related to a respective free(), seems to produce this.

According to this, there seems to be a maximum for mmap()ed chunks. If this is exceeded, gnulibc falls back to brk()/sbrk(), which operates on the "regular heap area".

So, shorter answer: The malloc()ed memory taken from via brk() is on the "real" [heap] section, the mmap()ed memory sections are not tagged as [heap].

like image 28
glglgl Avatar answered Sep 28 '22 00:09

glglgl