2

On Lubuntu 18.04

$ python3
>>> from ctypes import *
>>> libc = CDLL("libc.so.6")
>>> libc.printf
<_FuncPtr object at 0x7f10caf0d9a8>

I didn't specify path for libc.so.6, so how can CDLL() find its file to load?

Originated from Why does loading the libc shared library have "'LibraryLoader' object is not callable" error?

Tim
  • 1
  • 141
  • 372
  • 590

1 Answers1

2

That is because CDLL (or LibraryLoader or anything else from from [Python]: ctypes - A foreign function library for Python - and things can be expanded even more) uses the "native library loading system" in order to deal with library (searching and) loading (including dependencies).
On Ux systems, that is typically accomplished by the dynamic linker/loader.

Now, I assume that you're wondering why e.g. "/lib/x86_64-linux-gnu/libc.so.6" is found, even though "/lib/x86_64-linux-gnu" is not in ${LD_LIBRARY_PATH}.

From [man7]: LD.SO(8):

The program ld.so handles a.out binaries, a format used long ago; ld-linux.so* (/lib/ld-linux.so.1 for libc5, /lib/ld-linux.so.2 for glibc2) handles ELF, which everybody has been using for years now. Otherwise, both have the same behavior, and use the same support files and programs as ldd(1), ldconfig(8), and /etc/ld.so.conf.

From [man7]: LD(1):

The linker uses the following search paths to locate required shared libraries:
     ...
    8. For a native linker on an ELF system, if the file /etc/ld.so.conf exists, the list of directories found in that file.

Example on my VM:

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow]> uname -a
Linux cfati-ubtu16x64-0 4.13.0-43-generic #48~16.04.1-Ubuntu SMP Thu May 17 12:56:46 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow]> which ls
/bin/ls
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow]> file /bin/ls
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=d0bc0fb9b3f60f72bbad3c5a1d24c9e2a1fde775, stripped
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow]> ldd /bin/ls
        linux-vdso.so.1 =>  (0x00007ffc0e2e1000)
        libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f64b63d0000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f64b6006000)
        libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f64b5d96000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f64b5b92000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f64b65f2000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f64b5975000)
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow]> readelf -d /bin/ls

Dynamic section at offset 0x1de18 contains 25 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libselinux.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 ...

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow]> cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow]> ls -al /etc/ld.so.conf.d/*.conf
-rw-r--r-- 1 root root 32 iun  6 17:42 /etc/ld.so.conf.d/00vboxvideo.conf
-rw-rw-r-- 1 root root 38 nov 24  2014 /etc/ld.so.conf.d/fakeroot-x86_64-linux-gnu.conf
-rw-r--r-- 1 root root 44 ian 27  2016 /etc/ld.so.conf.d/libc.conf
-rw-r--r-- 1 root root 68 apr 15  2016 /etc/ld.so.conf.d/x86_64-linux-gnu.conf
lrwxrwxrwx 1 root root 43 mar  9 19:43 /etc/ld.so.conf.d/x86_64-linux-gnu_EGL.conf -> /etc/alternatives/x86_64-linux-gnu_egl_conf
lrwxrwxrwx 1 root root 42 mar  9 19:43 /etc/ld.so.conf.d/x86_64-linux-gnu_GL.conf -> /etc/alternatives/x86_64-linux-gnu_gl_conf
-rw-r--r-- 1 root root 56 ian 15 04:49 /etc/ld.so.conf.d/zz_i386-biarch-compat.conf
-rw-r--r-- 1 root root 58 ian 15 04:50 /etc/ld.so.conf.d/zz_x32-biarch-compat.conf
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow]> cat /etc/ld.so.conf.d/x86_64-linux-gnu.conf
# Multiarch support
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu

Since it's libc related, also check [SO]: How does ctypes.cdll.LoadLibrary(None) work? (@CristiFati's answer) in order to use the already loaded libc version (and avoid possible conflicts), if libc isn't linked statically.

CristiFati
  • 38,250
  • 9
  • 50
  • 87