From e61d02d5634966eb770a3b7b7373120b873803f6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 17 Oct 2026 02:39:30 +0200 Subject: [PATCH 1/2] gh-159603: Use pthread_attr_get_np() on FreeBSD Use pthread_attr_get_np() on FreeBSD to get the stack size (and guard size) of the current thread. Check if pthread_attr_get_np() function and header are available in configure. --- Python/ceval.c | 16 ++++++-- Tools/build/check_capi_macros_ignored.txt | 1 + configure | 49 +++++++++++++++++++++++ configure.ac | 5 ++- pyconfig.h.in | 6 +++ 5 files changed, 73 insertions(+), 4 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 43dc48f375301c..3566abe743079c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3,6 +3,11 @@ #include "ceval.h" #include "pycore_long.h" +#ifdef HAVE_PTHREAD_NP_H +# include // pthread_attr_get_np() +#endif + + int Py_GetRecursionLimit(void) { @@ -147,13 +152,18 @@ hardware_stack_limits(uintptr_t *base, uintptr_t *top, uintptr_t sp) // limits compared to the old stack size estimation. musl doesn't give // us a way to detect it, so we have to assume any non-glibc, // non-Android Linux is musl and mustn't rely on pthread_getattr_np. -# if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(_AIX) && \ - !defined(__NetBSD__) && \ - (defined(__GLIBC__) || defined(__ANDROID__) || !defined(__linux__)) +# if (defined(HAVE_PTHREAD_GETATTR_NP) || defined(_Py_HAVE_PTHREAD_ATTR_GET_NP)) \ + && !defined(_AIX) && !defined(__NetBSD__) \ + && (defined(__GLIBC__) || defined(__ANDROID__) || !defined(__linux__)) size_t stack_size, guard_size; void *stack_addr; pthread_attr_t attr; +#ifdef _Py_HAVE_PTHREAD_ATTR_GET_NP + int err = pthread_attr_init(&attr); + err |= pthread_attr_get_np(pthread_self(), &attr); +#else int err = pthread_getattr_np(pthread_self(), &attr); +#endif if (err == 0) { err = pthread_attr_getguardsize(&attr, &guard_size); err |= pthread_attr_getstack(&attr, &stack_addr, &stack_size); diff --git a/Tools/build/check_capi_macros_ignored.txt b/Tools/build/check_capi_macros_ignored.txt index 238c29b703968f..008eba4b417143 100644 --- a/Tools/build/check_capi_macros_ignored.txt +++ b/Tools/build/check_capi_macros_ignored.txt @@ -433,6 +433,7 @@ HAVE_PTHREAD_GET_NAME_NP HAVE_PTHREAD_H HAVE_PTHREAD_INIT HAVE_PTHREAD_KILL +HAVE_PTHREAD_NP_H HAVE_PTHREAD_SETNAME_NP HAVE_PTHREAD_SET_NAME_NP HAVE_PTHREAD_SIGMASK diff --git a/configure b/configure index 217d8e135600e1..72948d6ba4fb43 100755 --- a/configure +++ b/configure @@ -12073,6 +12073,12 @@ if test "x$ac_cv_header_pthread_h" = xyes then : printf "%s\n" "#define HAVE_PTHREAD_H 1" >>confdefs.h +fi +ac_fn_c_check_header_compile "$LINENO" "pthread_np.h" "ac_cv_header_pthread_np_h" "$ac_includes_default" +if test "x$ac_cv_header_pthread_np_h" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_NP_H 1" >>confdefs.h + fi ac_fn_c_check_header_compile "$LINENO" "pty.h" "ac_cv_header_pty_h" "$ac_includes_default" if test "x$ac_cv_header_pty_h" = xyes @@ -21814,6 +21820,49 @@ fi +# FreeBSD pthread_attr_get_np() + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_attr_get_np" >&5 +printf %s "checking for pthread_attr_get_np... " >&6; } +if test ${ac_cv_func_pthread_attr_get_np+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=pthread_attr_get_np + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_pthread_attr_get_np=yes +else case e in #( + e) ac_cv_func_pthread_attr_get_np=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_pthread_attr_get_np" >&5 +printf "%s\n" "$ac_cv_func_pthread_attr_get_np" >&6; } + if test "x$ac_cv_func_pthread_attr_get_np" = xyes +then : + +printf "%s\n" "#define _Py_HAVE_PTHREAD_ATTR_GET_NP 1" >>confdefs.h + +fi + + + + # os.statx uses Linux's statx function. AIX also has a function named statx, diff --git a/configure.ac b/configure.ac index ca804d6448810d..b8f5e2b3d5dd40 100644 --- a/configure.ac +++ b/configure.ac @@ -3195,7 +3195,8 @@ AC_CHECK_HEADERS([ \ alloca.h asm/types.h bluetooth.h conio.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/limits.h linux/memfd.h \ linux/netfilter_ipv4.h linux/random.h linux/soundcard.h linux/sched.h \ - linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ + linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h \ + poll.h process.h pthread.h pthread_np.h pty.h \ sched.h setjmp.h shadow.h signal.h spawn.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/pidfd.h sys/poll.h \ @@ -5586,6 +5587,8 @@ AC_CHECK_FUNCS([ \ PY_CHECK_FUNC_PRIVATE([freadlink], [@%:@include ]) PY_CHECK_FUNC_PRIVATE([strerror_r], [@%:@include ]) +# FreeBSD pthread_attr_get_np() +PY_CHECK_FUNC_PRIVATE([pthread_attr_get_np], [@%:@include ]) # os.statx uses Linux's statx function. AIX also has a function named statx, diff --git a/pyconfig.h.in b/pyconfig.h.in index 65e235c8fd6c93..0c8c7989a95f97 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1138,6 +1138,9 @@ /* Define to 1 if you have the 'pthread_kill' function. */ #undef HAVE_PTHREAD_KILL +/* Define to 1 if you have the header file. */ +#undef HAVE_PTHREAD_NP_H + /* Define to 1 if you have the 'pthread_setname_np' function. */ #undef HAVE_PTHREAD_SETNAME_NP @@ -2214,6 +2217,9 @@ /* Define if you have the 'PR_SET_VMA_ANON_NAME' constant. */ #undef _Py_HAVE_PR_SET_VMA_ANON_NAME +/* Define if you have the 'pthread_attr_get_np' function. */ +#undef _Py_HAVE_PTHREAD_ATTR_GET_NP + /* Define if you have the 'sinpi' function. */ #undef _Py_HAVE_SINPI From c031a553097da7ae3e3c42ca9de3fec0859973c1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 17 Oct 2026 02:47:27 +0200 Subject: [PATCH 2/2] Add Changelog entry --- .../2026-10-17-02-47-26.gh-issue-159603.OFagJz.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-10-17-02-47-26.gh-issue-159603.OFagJz.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-17-02-47-26.gh-issue-159603.OFagJz.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-17-02-47-26.gh-issue-159603.OFagJz.rst new file mode 100644 index 00000000000000..bd46b85509dbc2 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-17-02-47-26.gh-issue-159603.OFagJz.rst @@ -0,0 +1,2 @@ +On FreeBSD, call ``pthread_attr_get_np()`` to get the stack size (and guard +size) of the current thread. Patch by Victor Stinner.