Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: parts of a thread stack mapping, pthread_main_np()



On Sat, Apr 25, 2026 at 00:28:36 +0200, Thomas Klausner wrote:

> stack address: 0x7e610f000000, stack size: 4194304
> 
> and from pmap(1):
> 
> 00007E610EFF0000     64K                     [ anon ]
> 00007E610F000000   4032K read/write          [ anon ]
> 
> so I guess that explains that.  However, it looks like my change to
> stack(7) was incorrect and the guardsize should be subtracted to get
> the top address of the stack mapping, i.e.:
> 
>    +--------------------+ stack base = stackaddr + stacksize - guardsize
>    | stack              |
>    | .                  |
>    | .                  | <-- stack pointer
>    | .                  |       (varies during execution)
>    | V                  |
>    +--------------------+ stackaddr
>    | guard/redzone      |
>    +--------------------+ stackaddr - guardsize
>

pthread_attr_getstack(3) says (the last sentence is in the same
paragraph, but I split it off for emphasis):

     The stacksize parameter is defined to be the minimum stack size
     (in bytes) allocated for the thread's stack during the creation
     of the thread.  The stackaddr attribute specifies the location of
     storage to be used for the thread's stack.

   | All pages within the stack described by stackaddr and stacksize
   | should be both readable and writable by the thread.

The posix version of the text is at
https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_attr_getstack.html


So [addr, addr+size) is the actual stack.  Which end is the "base"
(bottom) depends on which way the stack grows (top).  For the common
case of the stack growing down (toward numerically smaller addresses),
the stack base is at the larger address, i.e. addr+size.

And the red zone must be after the other end of the stack, _outside_,
so addr-guardsize in this case.  This is your 0x7e610f000000 - 64*1024
= 0x7e610eff0000 - the no-access 64K mapping after (smaller addresses)
the 0x7e610f000000 stack address (the left side of the [addr,
addr+size) range).

The fact that for the stacksize of 0x400000 = 4096K, only 4032K is
mapped, seems like a bug that breaks that final "All pages..." part.

So, instead of

  +--------------------+ 7E61.0F40.0000 (base = addr+size)
  | stack              |
  | .                  |
  | .                  |
  | V                  |
  +--------------------+ 7E61.0F00.0000 (stackaddr)
  | guard/redzone      |
  +--------------------+ 7E61.0EFF.0000 (stackaddr - guardsize)


pmap shows:

  +--------------------+ 7E61.0F40.0000 (stackaddr + stacksize)
  | ???                |
  +--------------------+ 7E61.0F3F.0000 (stackaddr + stacksize - guardsize)
  | stack              |
  | .                  |
  | .                  |
  | V                  |
  +--------------------+ 7E61.0F00.0000 (stackaddr)
  | guard/redzone      |
  +--------------------+ 7E61.0EFF.0000 (stackaddr - guardsize)


Relevant code is in pthread__getstack() in lib/libpthread/pthread.c

-uwe


Home | Main Index | Thread Index | Old Index