[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