Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thread-unsafe libc functions #127081

Open
colesbury opened this issue Nov 20, 2024 · 0 comments
Open

Thread-unsafe libc functions #127081

colesbury opened this issue Nov 20, 2024 · 0 comments
Labels
topic-free-threading type-bug An unexpected behavior, bug, or error

Comments

@colesbury
Copy link
Contributor

colesbury commented Nov 20, 2024

Bug report

There are a a few non thread-safe libc functions used in Python that can be an issue for free threading, isolated subinterpreters, or sometimes even with the GIL.

In #126316, @vstinner fixed the use setgrent / getgrent. It's probably a good time to look for other similar issues.

clang-tidy

clang-tidy has a concurrency-mt-unsafe check that looks for "known-to-be-unsafe functions".

clang-tidy notes

Prerequisites: install clang-tidy-18 and bear.

./configure -C --with-pydebug --disable-gil

# generate compile_commands.json
bear -- make -j 

run-clang-tidy-18 -checks='-*,concurrency-mt-unsafe' -p .

Unsafe libc functions

  • localeconv(): not thread-safe, see glibc's manual. Is nl_langinfo a substitue?
  • setlocale
  • setpwent, getpwent, and endpwent in pwdmodule.c. These are similar to grpmodule.c and can likely be addressed the same way.
  • getservbyname, getservbyport, getprotobyname in Modules/socketmodule.c: use getservbyname_r, etc.? Note these thread-safety issues affect the default build because we release the GIL around the relevant calls.
  • dbm_open, dbm_close, etc. in Modules/_dbmmodule.c
  • getlogin: use getlogin_r if available?

Unfixable by us?

  • getenv, setenv, unsetenv, putenv: environment modification isn't thread-safe and getenv is used extensively in other C libraries, so putting a lock around our accesses doesn't do much. (Might finally be fixed in glibc, see https://inbox.sourceware.org/libc-alpha/[email protected]/).
  • login_tty: not sure it matters as login_tty is usually called after a fork()

Safe due to our usage

  • getc_unlocked, safe because we use it within a flockfile() call.
  • mbrtowc() - safe as long as the passed in mbstate_t * is non-NULL, which is the case in CPython.

Safe in glibc

These functions are flagged by clang-tidy because they are not guaranteed to be safe by POSIX, but they are safe in glibc. It'd be nice to verify that they are safe in other libc implementations. I don't think it's worth changing them:

Other

  • exit(): apparently concurrent calls to exit() are not thread-safe, but I don't think it matters for our usages.
  • ptsname(): we already use ptsname_r(), but the static analyzer gets confused
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-free-threading type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

1 participant