Skip to content

gh-153400: Resolve newer libc/syscall wrappers at runtime on Linux#153398

Open
daandemeyer wants to merge 1 commit into
python:mainfrom
daandemeyer:posix-runtime-libc-shims
Open

gh-153400: Resolve newer libc/syscall wrappers at runtime on Linux#153398
daandemeyer wants to merge 1 commit into
python:mainfrom
daandemeyer:posix-runtime-libc-shims

Conversation

@daandemeyer

@daandemeyer daandemeyer commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

os functions like copy_file_range() are gated on a configure-time AC_CHECK_FUNCS probe and compiled out when the build libc lacks the symbol. A redistributable built against an old glibc (the python-build-standalone builds target glibc 2.17) therefore never exposes them, even when run on a newer glibc or a capable kernel.

Add Modules/posixshims.h, which on Linux always exposes Py(), resolves the libc symbol once at load time via dlsym(RTLD_DEFAULT) from a constructor, and falls back to the raw syscall when the running libc lacks the wrapper. Resolving in a constructor keeps dlsym(), which is not async-signal-safe, out of signal handlers and the fork()/exec() window. Off Linux the classic build-time HAVE_* direct calls are kept.

Limit the shims to wrappers newer than the glibc 2.17 baseline, since anything at or below it is always present in the build libc:

copy_file_range (glibc 2.27)
memfd_create (glibc 2.27)
pidfd_open (glibc 2.36)
pidfd_getfd (glibc 2.36)

pidfd_open() and pidfd_getfd() previously issued raw syscalls unconditionally; they now prefer the glibc wrapper when present.

@python-cla-bot

python-cla-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

@daandemeyer daandemeyer force-pushed the posix-runtime-libc-shims branch from 0fe670a to 9a8baaa Compare July 9, 2026 08:00
@picnixz

picnixz commented Jul 9, 2026

Copy link
Copy Markdown
Member

Sorry but this needs an issue. It is a nontrivial change.

@daandemeyer daandemeyer force-pushed the posix-runtime-libc-shims branch from 9a8baaa to 4d76954 Compare July 9, 2026 08:21
@daandemeyer daandemeyer changed the title Resolve newer libc/syscall wrappers at runtime on Linux gh-153400: Resolve newer libc/syscall wrappers at runtime on Linux Jul 9, 2026
Comment thread Modules/posixshims.h Outdated
@daandemeyer daandemeyer force-pushed the posix-runtime-libc-shims branch from 4d76954 to b7a07aa Compare July 9, 2026 08:49

@picnixz picnixz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A nicer error message should be emitted if we lack the functions I think rather than an unresolvable symbol error

Comment thread Modules/posixshims.h
#elif defined(HAVE_COPY_FILE_RANGE)
# define _Py_HAVE_COPY_FILE_RANGE
# define _Py_copy_file_range copy_file_range
#endif

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the else branch?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure what you meant here, I've added fallbacks if the syscall numbers are not available.

@daandemeyer daandemeyer force-pushed the posix-runtime-libc-shims branch 2 times, most recently from 9f3b446 to 4348bb9 Compare July 9, 2026 09:59
@daandemeyer

Copy link
Copy Markdown
Contributor Author

A nicer error message should be emitted if we lack the functions I think rather than an unresolvable symbol error

We'll get a "function not implemented" OSError if the syscalls are not available, do you expect anything more?

os functions like copy_file_range() are gated on a configure-time
AC_CHECK_FUNCS probe and compiled out when the build libc lacks the
symbol. A redistributable built against an old glibc (the
python-build-standalone builds target glibc 2.17) therefore never
exposes them, even when run on a newer glibc or a capable kernel.

Add Modules/posixshims.h, which on Linux always exposes _Py_<func>(),
resolves the libc symbol once at load time via dlsym(RTLD_DEFAULT) from a
constructor, and falls back to the raw syscall when the running libc
lacks the wrapper. Resolving in a constructor keeps dlsym(), which is not
async-signal-safe, out of signal handlers and the fork()/exec() window.
Off Linux the classic build-time HAVE_* direct calls are kept.

Limit the shims to wrappers newer than the glibc 2.17 baseline, since
anything at or below it is always present in the build libc:

  copy_file_range (glibc 2.27)
  memfd_create    (glibc 2.27)
  pidfd_open      (glibc 2.36)
  pidfd_getfd     (glibc 2.36)

pidfd_open() and pidfd_getfd() previously issued raw syscalls
unconditionally; they now prefer the glibc wrapper when present.
@daandemeyer daandemeyer force-pushed the posix-runtime-libc-shims branch from 4348bb9 to 566bb9f Compare July 9, 2026 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants