Hacker News new | ask | show | jobs
by monocasa 2485 days ago
So this is a whole lot more complicated these days. There's not one stack but many for the different threads, regions have guard pages typically, and all these regions are setup with mmap (so there's no sbrk syscall anymore) just for starters.
4 comments

    strace ls
    execve("/usr/bin/ls", ["ls"], 0x7ffd86646d90 /* 61 vars */) = 0
    brk(NULL)                               = 0x5581b6542000
I see brk(), that's glibc.
Does malloc() use brk() or mmap()?

https://stackoverflow.com/questions/30542428/does-malloc-use...

    there is a mallopt named M_MMAP_THRESHOLD, in general:
    
    If requested memory is less than it, brk() will be used;
    If requested memory is larger than or equals to it, mmap() will be used;
This is linux-specific though. Non-glibc mallocs have different tuning and many have completely foresworn brk/sbrk (openbsd and dragonflybsd mallocs haven't used brk in more than a decade[0]). In fact brk/sbrk is deprecated in every BSD:

On OpenBSD, DragonflyBSD, NetBSD and OSX:

> The brk and sbrk functions are historical curiosities left over from earlier days before the advent of virtual memory management.

On FreeBSD:

> The brk() and sbrk() functions are legacy interfaces from before the advent of modern virtual memory management. They are deprecated and not present on the arm64 or riscv architectures.

It's also somewhat discouraged on Solaris:

> The behavior of brk() and sbrk() is unspecified if an application also uses any other memory functions (such as malloc(3C), mmap(2), free(3C)).

[0] https://bugs.dragonflybsd.org/issues/84

Depends on system. In FreeBSD brk() syscall doesn’t even exist on newer platforms, such as RISC-V or aarch64.
In OpenBSD, brk/sbrk still exist but they removed its use from malloc something like 15 years ago.
If you go into the kernel, it's implemented in terms of mmap/munmap.
If you go into the kernel, all this is implemneted with page tables and MMUs.
You said there was no sbrk syscall, and there is.
brk() is undefined behavior if mmap is ever called.
I was wrong, it's only if you use MAP_FIXED to map an overlapping area.
How so? Both syscalls are invoked pretty frequently together in the same program.
Wow that's news to me - can you point me at the documentation for that?
Can you post a definite source supporting this?
There isn't one, because it's wrong.

Source: run strace on almost any useful Linux command (e.g. ls, sort, which, ...), you'll see it makes calls to both brk() and mmap().

The OP admitted it was wrong, but just because everyone does it doesn't mean it's not undefined behavior.
man syscalls disagrees with you, brk is there just fine.
They probably mean that it's no longer used by the allocator which will be using nmap instead (although obviously that will depend on what allocator you use). The syscall itself is going nowhere.
is there a good reference you'd recommend?
Also very important with 64 bit there is a lot more room to play with. Also there is address layout randomization which at last on 64bit every program _should_ be compiled with.

Also on 64 bit isn't the last memory page like the first unmappable (I think at last on linux it is).

Lastly isn't there a region of unmapable virtual address space on 64 bit in the middle of the virtual address space due to the chips which are doing mmap not handling full 64bit of virtual address space?? I sadly can't find any info about this but I remember having read about it before? Maybe I mixed something up.

> Lastly isn't there a region of unmapable virtual address space on 64 bit in the middle of the virtual address space due to the chips which are doing mmap not handling full 64bit of virtual address space?

Yes. ARM64 currently has a 48b address space split in two ranges (0 to 00007FFFFFFFFFFF and FFFF800000000000 to FFFFFFFFFFFFFFFF), ARMv8 requires 48b and allows 52 but apparently the sizes of the userspace and kernel regions are configurable (though limited by the chip aka you could reduce the size of the kernel space down from 48b but can't increase it).