1

Running this piece of code is supposed to cause program break to increase by about malloc_counts * _SC_PAGESIZE instead I get fixed program break each time, so why is this. malloc is supposed to call brk or sbrk which itself round up size passed to next page (with some extra work). So what's happening ?

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

int main(){
    const long malloc_counts = 10;
    printf("PAGE SIZE: %ld\n", sysconf(_SC_PAGESIZE));
    void* allocated_pool[malloc_counts];
    for(int counter=0; counter < malloc_counts; counter++)
    {
        printf("program brk: %p\n",sbrk(0));
        allocated_pool[counter] = malloc(127*4096);
    }
}
KMG
  • 1,433
  • 1
  • 8
  • 19
  • 1
    `counter <= malloc_counts;` will cause array overflow when`counter == malloc_counts;` – Weather Vane Sep 14 '20 at 18:54
  • 1
    Linux's `malloc` can use either `sbrk` or `mmap` to acquire memory, and the latter won't change the break point. I don't know how the current algorithm decides which to use. Youl could use `strace` to see what's being done. – Nate Eldredge Sep 14 '20 at 18:56
  • The loop condition `counter <= malloc_counts` should use the less-then comparison operator instead of less-or-equal. – CiaPan Sep 14 '20 at 18:57
  • @CiaPanI fixed this typo now. – KMG Sep 14 '20 at 19:12
  • Try with ex. `malloc(127 * 4096);` – KamilCuk Sep 14 '20 at 19:16
  • @KamilCuk same Thing Nothing change – KMG Sep 14 '20 at 19:19
  • Same? Really? Changes for me. What standard library version are you using? Please, if you could, make the code fully compilable source code - guessing `#include`s and adding `int main()` is no fun. What does `mallinfo` return on each loop? `malloc_stats`? `mallopt` with `M_MMAP_THRESHOLD` would be interesting also. [can't reproduce, godbolt link](https://godbolt.org/z/PsKsxj) What is the value of `malloc_counts`? – KamilCuk Sep 14 '20 at 19:21
  • @kamilCuk glibc 2.31 , but even if it worked for you, ```127 * 4096``` is a very large amount much greater than a linux page size(more than one page is needed), which is even more confusing since it doesn't seem to be different with me . – KMG Sep 14 '20 at 19:26
  • 1
    @kamilCuk I added whole source code now – KMG Sep 14 '20 at 19:32
  • How are you compiling the code? Are you compiling with optimizations? What "linux" are you using? My current bet is that you are compiling with optimizations enabled... if not, please post malloc statistics along the way and the value of `M_MMAP_THRESHOLD`. – KamilCuk Sep 14 '20 at 19:33
  • @KamilCuk i'm running Ubuntu20 and compiling using Clion defaults(which i guess of course using optimizations).Can you tell me what's the result if you made malloc size same as page-size of maybe even a little bit larger. – KMG Sep 14 '20 at 19:36
  • @KamilCuk just tried manually compiling using ```gcc prog.c``` still noeffect . – KMG Sep 14 '20 at 19:42
  • Try `gcc -O0 prog.c` to be sure. If not, as said, query malloc information and query M_MMAP_THRESHOLD and see what is going on. Also inspect the assembly and confirm that `malloc` calls are really there and not optimized out. – KamilCuk Sep 14 '20 at 19:43
  • Ach, `127*4096` is too much! to `127*1024`, my bad. The defualt `M_MMAP_THRESHOLD` is `128*1024` – KamilCuk Sep 14 '20 at 19:45

1 Answers1

2

which i guess of course using optimizations

Your compiler optimizes the calls to malloc out, because they are unused. Because malloc calls are removed, nothing changes and the heap is not moved.

And glibc overallocates a lot, so the value has to be large enough for it to see it. And the default M_MMAP_THRESHOLD seem to be 128 * 1024. So you have to pick a value large enough, but below mmap threshold to see a difference in glibc.

Disable your compiler optimizations and allocate a lot and heap will be moved. Try the following:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
    printf("PAGE SIZE: %ld\n", sysconf(_SC_PAGESIZE));
    #define malloc_counts  20
    void *allocated_pool[malloc_counts];
    for(int counter = 0; counter < malloc_counts; counter++) {
        printf("program brk: %p\n", sbrk(0));
        allocated_pool[counter] = malloc((size_t)127 * 1024);
        *(void *volatile *)&allocated_pool[counter];
    }
}
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • ```M_MMAP_THRESHOLD``` is ```-3``` which i don't know what it means yet – KMG Sep 14 '20 at 19:49
  • malloc is seemed to be fine and being called(not optimized out) found this line ``` callq 10e0 ``` , so is this problem is only with me, I mean is above code in the question working for you normally. – KMG Sep 14 '20 at 20:00