Bug 32574 - pthread_attr_getstacksize/pthread_attr_getstack return incorrect main stack size
Summary: pthread_attr_getstacksize/pthread_attr_getstack return incorrect main stack size
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: 2.42
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-01-19 14:47 UTC by John David Anglin
Modified: 2025-01-29 23:41 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John David Anglin 2025-01-19 14:47:12 UTC
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>

int
main (void)
{
  pthread_attr_t attr;
  size_t size;
  void *stackaddr;

  (void) pthread_getattr_np(pthread_self(), &attr);
  (void) pthread_attr_getstack(&attr, &stackaddr, &size);
  printf ("stackaddr = 0x%x size = 0x%x\n", stackaddr, size);
  return 0;
}

The above program prints the default initial main stack size.  Similar code
exists in ruby thread-pthread.c.

The default main stack size on hppa is 135168.  It is approximately
8380416 on x86.  There is some variation due to randomization.

The small initial main stack on hppa causes various recursive tests
in ruby to fail even though there is still lots of room for the stack
to grow.

The size of the stack mmap region in /proc/self/maps on hppa and x86 is
identical (135168 bytes).

On x86, the stack size returned is roughly rl.rlim_cur - 135168.  I
believe as the stack grows downward (mmap region gets larger), the x86
stack size gets smaller.  I may be wrong but I don't believe the value
returned on x86 is consistent with the Open Group specification.

This change makes hppa behave like x86:

diff --git a/nptl/pthread_getattr_np.c b/nptl/pthread_getattr_np.c
index e98e2df152..43dd16d59c 100644
--- a/nptl/pthread_getattr_np.c
+++ b/nptl/pthread_getattr_np.c
@@ -145,9 +145,9 @@ __pthread_getattr_np (pthread_t thread_id, pthread_attr_t *attr)
                          > (size_t) iattr->stackaddr - last_to)
                        iattr->stacksize = (size_t) iattr->stackaddr - last_to;
 #else
-                     /* The limit might be too high.  */
+                     /* The limit might be too low.  */
                      if ((size_t) iattr->stacksize
-                         > to - (size_t) iattr->stackaddr)
+                         < to - (size_t) iattr->stackaddr)
                        iattr->stacksize = to - (size_t) iattr->stackaddr;
 #endif
                      /* We succeed and no need to look further.  */

But I think the x86 code is wrong.  Shouldn't pthread_attr_getstacksize and pthread_attr_getstack return the actual stack size at the time of their
call?  They currently return the unallocated residual.  getrlimit can be
be used to get the maximum size of the process stack.

Open Group spec says:

The stacksize attribute shall define the minimum stack size (in bytes) allocated for the created threads stack.
Comment 1 Sam James 2025-01-29 23:41:57 UTC
commit 8e86549d1417a4618ab98d10aaba427350b321c6 (HEAD -> master, origin/master, origin/HEAD)
Author: John David Anglin <danglin@gcc.gnu.org>
Date:   Wed Jan 29 16:51:16 2025 -0500

    nptl: Correct stack size attribute when stack grows up [BZ #32574]

    Set stack size attribute to the size of the mmap'd region only
    when the size of the remaining stack space is less than the size
    of the mmap'd region.

    This was reversed.  As a result, the initial stack size was only
    135168 bytes.  On architectures where the stack grows down, the
    initial stack size is approximately 8384512 bytes with the default
    rlimit settings.  The small main stack size on hppa broke
    applications like ruby that check for stack overflows.

    Signed-off-by: John David Anglin <dave.anglin@bell.net>

Fixed in 2.42.