Can memory allocated through mmap overlap a data segment

The malloc function uses the sbrk and mmap functions. The sbrk function sbrk increases or decreases the data segment. So it grows linearly. Now my question is, is this linearity always maintained, or, for example, can the mmap call allocate memory that overlaps a data segment?

I am talking about multi-threaded programs running on multi-core systems. This blog talks about some of the serious drawbacks of sbrk for multi-threaded programs, and it indicates that it is possible that the memory allocated with sbrk can be mixed with alloacted memory with mmap (the sbrk heap may become intermittent because the mmaped area or the shared object interferes heap growth).

+4
source share
2 answers

This blog post does not see a forest for trees; only the malloc implementation is allowed to call sbrk with a non-zero argument. More precisely, most of the malloc implementations for Unix will stop functioning correctly (and by this I mean "your program will work") if the application code calls sbrk with a non-zero argument. If you want to make a big selection directly from the OS, you should use mmap for this.

(It is true that in a multi-threaded malloc program, you must internally wrap the mutex around your sbrk calls, but this is an implementation detail. POSIX says that malloc is thread safe, which is an important thing for an application programmer.)

mmap will not allocate memory that spans the brk area unless you use MAP_FIXED . If you use MAP_FIXED and your program explodes, you can save all the shapes.

The kernel tries to avoid this, but mmap during normal operation may involve allocating memory near the top of the brk . If this happens, a subsequent sbrk call that encounters the mmap scope will fail. He will not allocate non-contiguous memory. Good malloc implementations should discover this condition and start using mmap for everyone. I have not actually tried, but the test program would be fairly easy to write.

+12
source

Is this linearity always supported or, for example, can the mmap call allocate memory that spans a data segment?

The observed behavior is that the brk region is always linear. Implementation Details: If expanding the brk region is not possible, for example, due to a blocking display, glibc will switch to mmap-only. Small allocations (<128 Kbytes) are apparently obtained with glibc via brk, if possible, therefore blocking with:

 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> int main(void) { int i; for (i = 0; i < 1024; ++i) { malloc(2048); if (i == 512) { void *r, *end = sbrk(0); r = mmap(end, 4096, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); } } } 

when he suffers, gives really

 [...] brk(0x1e7d000) = 0x1e7d000 mmap(0x1e7d000, 4096, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) = 0x1e7d000 brk(0x1e9e000) = 0x1e7d000 <-- (!) mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbfd9bc9000 
+3
source

Source: https://habr.com/ru/post/1397479/


All Articles