-
-
Notifications
You must be signed in to change notification settings - Fork 29.5k
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
ctypes.util.find_library("libc") fails #86746
Comments
regression compared to 3.8: $ python3.9
Python 3.9.1rc1 (default, Nov 27 2020, 19:38:39)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> ctypes.util.find_library("libc")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'ctypes' is not defined
>>> import ctypes.util
>>> ctypes.util.find_library("libc")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.9/ctypes/util.py", line 341, in find_library
_get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name))
File "/usr/lib/python3.9/ctypes/util.py", line 147, in _findLib_gcc
if not _is_elf(file):
File "/usr/lib/python3.9/ctypes/util.py", line 99, in _is_elf
with open(filename, 'br') as thefile:
FileNotFoundError: [Errno 2] No such file or directory: b'liblibc.a' also note that the shared library is installed. |
ctypes.util.find_library("c") works in both 3.8 and 3.9 |
can't reproduce (py39) ➜ ~ ipython In [1]: import ctypes.util |
This function is quite complicated on Linux: def find_library(name):
# See issue python/cpython#54207
return _findSoname_ldconfig(name) or \
_get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name)) _findSoname_ldconfig() uses "/sbin/ldconfig -p" and searchs for 'libc6,x86-64' in the output (on x86-64). _findLib_gcc() uses "gcc -Wl,-t -o tmp -lc" command and search for "lib" in the created "tmp" file. _findLib_ld() uses "ld -t -lc" command and searchs for "lib" pattern. The exact code is more complicated :-) You should debug this issue by running these commands manually on Debian. Note: python3.9 -c 'import ctypes.util; print(ctypes.util.find_library("c"))' commands displays libc.so.6 with Python 3.8, 3.9 and 3.10 on Fedora. I cannot reproduce the issue on Fedora 33 (x86-64). |
Oh, it looks for the "lib" in the process stdout (not in the created "tmp" file). |
Note, that adding "lib" prefix to any library is wrong, that's why it returns "None" or raises the exception. And it works fine when you call find_library("c") I guess the issue, that was reported here, is about raising and exception instead of returning "None", but not about finding library, isn't it? |
Oh right, I always use find_library("c"), not find_library("libc"). |
So, can we close it? |
ctypes.util.find_library("libc") used to work in 3.8, not working in 3.9. As I said before, ctypes.util.find_library("c") works in both 3.8 and 3.9. |
bpo-41976 added ctypes.util._is_elf() to filter out linker scripts such as "libc.so". The PR was backported to 3.7. _is_elf() assumes the trace result has absolute paths that can be opened, but Matthias is getting the relative filename "liblibc.a" in the result. Whatever the reason, I think if the file can't be opened for reading, then _is_elf() should just return False. For example: def _is_elf(filename):
"Return True if the given file is an ELF file"
elf_header = b'\x7fELF'
try:
with open(filename, 'br') as thefile:
return thefile.read(4) == elf_header
except OSError:
return False |
no, it doesn't work (and it shouldn't) neither in python 3.8 nor 3.7
import ctypes.util
a = ctypes.util.find_library("libc")
print(a)
None as I said, adding prefix "lib" is wrong |
I mean, find_library relies on gcc linker, when you pass library name to the linker, it automatically ads "lib" prefix to the library just man ld and see "-l" option: " as you can see, you pass not a library name, but a "namespec" |
The documentation is explicit: you must not include the "lib" prefix. See also examples: If it worked with "lib" prefix in Python 3.8, it wasn't on purpose. You should fix your code, but Python works as expected. I close the issue. |
Can't there be a library named "libc" with the shared module "liblibc.so"? It seems to me that the _is_elf() function added in bpo-41976 is breaking the contract that "[i]f no library can be found, returns None". It's not supposed to leak arbitrary exceptions from the implementation if the library isn't found. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: