Where are the stacks for the other threads located in a process virtual address space?

后端 未结 2 546
南笙
南笙 2020-12-10 04:55

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

相关标签:
2条回答
  • 2020-12-10 05:32

    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...

    0 讨论(0)
  • 2020-12-10 05:41

    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.

    0 讨论(0)
提交回复
热议问题