gh-65821: Fix ctypes.util.find_library with musl by ncopa · Pull Request #18380 · python/cpython (original) (raw)
Anyway, regardless of if I think this is a good idea to have or not, as I said above, the new search mechanism you are introducing is not limited to musl. So, if this was ever to be merged, it should at least limit this search routine to musl. But I am not the maintainer, I am just giving my opinion.
I find that unfair. Current _findSoname_ldconfig
search routine is not limited to GNU libc, but comment says that GNU libc is assumed. Why should we limit search routing for musl when we don't do it for GNU libc?
That said, I started to look at how to fix the issues you have raised. I believe the {name}.so
claim is bogus, but can add that to the search list if I can get a specific real world test case.
Finding the correct $ARCH
for /etc/ld-musl-$ARCH.path
is a more tricky problem, but can be solved with by finding the PT_INTERP
using dl_iterate_phdr (thanks to @nsz-arm for this):
#include <elf.h> #include <link.h> #include <stdio.h>
static int cb(struct dl_phdr_info *info, size_t size, void *data) { const char **ps = data; const char *base = (const char *)info->dlpi_addr; const ElfW(Phdr) *ph = info->dlpi_phdr; int phn = info->dlpi_phnum;
for(int i=0; i < phn; i++) {
if (ph[i].p_type == PT_INTERP) {
*ps = base + ph[i].p_vaddr;
return 1;
}
}
return 0;
}
const char *get_interp() { const char *s = 0; int r = dl_iterate_phdr(cb, &s); return r == 1 ? s : 0; }
int main() { printf("%s\n", get_interp()); }
it will print the interpreter (eg /lib/ld-musl-$ARCH.so.1
). I think this can also be used to pick the correct /lib/libc.musl-$ARCH.so.*
, which current implementation ('.musl-*.so.[0-9]*'
) may pick wrong.
However, using dl_iterate_phrd
requires some C glue and configure.ac
tests, since its not available on all platforms, and I'm not sure how to implement this C glue.
BTW, in the current implementation, running a 32 bit python binary on a 64 bit host will find 64 bit libraries:
$ docker run --rm -it ubuntu sh -c "dpkg --add-architecture i386 && apt-get update -y && apt-get install -y python3:i386 && python3 -c 'import platform; print(platform.architecture())' && python3 -c \"import ctypes.util; print(ctypes.util.find_library('systemd'))\" | xargs find /usr -name
...
('32bit', 'ELF')
/usr/lib/x86_64-linux-gnu/libsystemd.so.0
So I'm thinking that making things simple by parsing all /etc/ld-musl-*.path
files might be good enough. What do you think?