The following image shows where the sections of a process are laid out in the process\'s virtual address space (in Linux):
You can see that there is only on
As far as I can remember, the space devoted to process stack is divided into smaller portion, each one used by a given thread. There are also some guard pages in between to prevent accidental smashing. And yes, stacks are one below others...
Stack space for a new thread is created by the parent thread with mmap(MAP_ANONYMOUS|MAP_STACK). So they're in the "memory map segment", as your diagram labels it. It can end up anywhere that a large malloc()
could go. (glibc malloc(3)
uses mmap(MAP_ANONYMOUS)
for large allocations.)
(MAP_STACK
is currently a no-op, and exists in case some future architecture needs special handling).
You pass a pointer to the new thread's stack space to the clone(2) system call which actually creates the thread. (Try using strace -f
on a multi-threaded process sometime). See also this blog post about creating a thread using raw Linux syscalls.
See this answer on a related question for some more details about mmaping stacks. e.g. MAP_GROWSDOWN
doesn't prevent another mmap()
from picking the address right below the thread stack, so you can't depend on it to dynamically grow a small stack the way you can for the main thread's stack (where the kernel reserves the address space even though it's not mapped yet).
So even though mmap(MAP_GROWSDOWN)
was designed for allocating stacks, it's so bad that Ulrich Drepper proposed removing it in 2.6.29.
Also, note that your memory-map diagram is for a 32-bit kernel. A 64-bit kernel doesn't have to reserve any user virtual-address space for mapping kernel memory, so a 32-bit process running on an amd64 kernel can use the full 4GB of virtual address space. (Except for the low 64k by default (sysctl vm.mmap_min_addr = 65536
), so NULL-pointer dereference does actually fault.)
related:
See Relation between stack limit and threads for more about stack-size for pthreads. getrlimit(RLIMIT_STACK)
is the main thread's stack size. Linux pthreads uses RLIMIT_STACK
as the stack size for new threads, too.