[PATCH v2] nptl: pthread_getattr_np: Read /proc/self/maps in BUFSIZ chunks, avoid fstat

Andreas K. Huettel dilfridge@gentoo.org
Thu Jul 23 12:03:28 GMT 2026


Am Donnerstag, 23. Juli 2026, 13:57:47 Japanische Normalzeit schrieb Josh Triplett:
> pthread_getattr_np gets stack information by reading /proc/self/maps.
> This file, like all proc inodes, reports a size of 1024, regardless of
> its actual content. In practice, it tends to be several times that size.
> So, use our BUFSIZ instead.
> 
> This also avoids an unnecessary `fstat`.
> 
> This requires us to allocate a buffer ourselves, since otherwise the
> default logic in `setvbuf` will ignore our requested size in favor of
> the stat-based heuristics.

After the release please. TIA

> 
> strace before:
> ```
> openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3
> prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
> fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
> read(3, "558bccc5a000-558bccc6e000 r--p 0"..., 1024) = 1024
> read(3, "                  /usr/lib/x86_6"..., 1024) = 1024
> read(3, "             /usr/lib/x86_64-lin"..., 1024) = 670
> close(3)                                = 0
> ```
> 
> strace after:
> ```
> openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3
> prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
> read(3, "55556b7ab000-55556b7cc000 rw-p 0"..., 8192) = 2753
> close(3)                                = 0
> ```
> 
> Note the single `read` call and the absent `fstat`.
> 
> Signed-off-by: Josh Triplett <josh@joshtriplett.org>
> ---
> v2: Use `_IO_setvbuf` rather than `setvbuf` to avoid the PLT.
> 
> I don't have commit access yet, so I'd appreciate it if a reviewer could
> commit this for me once accepted.
> 
>  nptl/pthread_getattr_np.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/nptl/pthread_getattr_np.c b/nptl/pthread_getattr_np.c
> index b0d2343a59..659323fc9c 100644
> --- a/nptl/pthread_getattr_np.c
> +++ b/nptl/pthread_getattr_np.c
> @@ -23,6 +23,7 @@
>  #include <stdlib.h>
>  #include <string.h>
>  #include <sys/resource.h>
> +#include "iolibio.h"
>  #include "pthreadP.h"
>  #include <lowlevellock.h>
>  #include <ldsodefs.h>
> @@ -88,10 +89,23 @@ __pthread_getattr_np (pthread_t thread_id, pthread_attr_t *attr)
>        /* We need the limit of the stack in any case.  */
>        else
>  	{
> +	  char *fp_buf = NULL;
>  	  if (__getrlimit (RLIMIT_STACK, &rl) != 0)
>  	    ret = errno;
>  	  else
>  	    {
> +	      /* /proc/self/maps reports a size of 1024, like all proc inodes.
> +		 However, in practice it tends to be larger than that. Use our
> +		 default BUFSIZ instead. We have to allocate the buffer
> +		 ourselves, because if we don't, setvbuf ignores the requested
> +		 size and uses the file size. */
> +	      fp_buf = malloc(BUFSIZ);
> +	      if (fp_buf && _IO_setvbuf (fp, fp_buf, _IOFBF, BUFSIZ) != 0)
> +		{
> +		  free(fp_buf);
> +		  fp_buf = NULL;
> +		}
> +
>  	      /* We consider the main process stack to have ended with
>  	         the page containing __libc_stack_end.  There is stuff below
>  		 it in the stack too, like the program arguments, environment
> @@ -163,6 +177,7 @@ __pthread_getattr_np (pthread_t thread_id, pthread_attr_t *attr)
>  	    }
>  
>  	  fclose (fp);
> +	  free (fp_buf);
>  	}
>      }
>  
> 


-- 
PD Dr. Andreas K. Hüttel
dilfridge@gentoo.org
Gentoo Linux developer 
(council, comrel, toolchain, base-system, perl, libreoffice)
https://wiki.gentoo.org/wiki/User:Dilfridge




More information about the Libc-alpha mailing list