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
bpo-21622: Fix ctypes.util.find_library with musl #18380
base: main
Are you sure you want to change the base?
Conversation
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept this contribution by verifying everyone involved has signed the PSF contributor agreement (CLA). CLA MissingOur records indicate the following people have not signed the CLA: For legal reasons we need all the people listed to sign the CLA before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. If you have recently signed the CLA, please wait at least one business day You can check yourself to see if the CLA has been received. Thanks again for the contribution, we look forward to reviewing it! |
What's the status on this? As seen by the mention, this is required to make some stuff work on Musl systems. |
Although I do want to see this resolved, I don't believe the current implementation is correct.
Trying to duplicate the ld search logic is difficult, system dependent and can very easily get out of date. If there is no other option to solve this for musl, this new search routine should at least only be used when ldconfig
is not present, but even then I am not super comfortable with it.
It is some time since I worked on this, but I think my conclusion was that there is not really any way to implement this correctly (at least not in a portable way), so this is only an attempt to get it working on current known use cases. |
Right, and that is reasonable for a downstream patch, but I am not too comfortable having it in the upstream. I generally think it is better to have something not working, which forces users to work around it in a way that works for their use-case, than to have something with broken behavior. 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 That said, I started to look at how to fix the issues you have raised. I believe the Finding the correct #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 However, using BTW, in the current implementation, running a 32 bit python binary on a 64 bit host will find 64 bit libraries:
So I'm thinking that making things simple by parsing all |
I don't know, why should we improve things? I will refrain from commenting further. I have made my suggestions, but they were just that. It is up to the maintainers to make the call. This code gives me anxiety and I would not merge it as is. Everybody is happy until things break and you are the one who has to fix them Perhaps you should write to the musl mailing list asking for advice on how to approach this. |
musl list won't help much. this is a bug python dig for itself: the exposed api has semantics that is impossible to implement on a posix system including glibc and musl. i've seen this fail on glibc too and it will cause more trouble as python is used in more custom environments. so it's up to the python community to figure out what they want find_library to mean. the dynamic linker search path logic is not a public api and can change (musl or glibc may introduce new mechanisms to configure it) and there is no guarantee that a library exists in the filesystem (which is e.g. the case for libpthread.so in musl: dlopen gives a handle to it but there is no libpthread.so in the filesystem or similar can happen with kernel mapped shared libraries like the vdso if they get exposed via dlopen or already loaded but then deleted files). |
@FFY00 Thank you for taking time to review and comment. I understand that the code gives you anxiety. The whole file gives me anxiety I think the I did get help from musl devs on IRC who came up with the |
I'd like to see this fixed upstream, but I don't believe this PR or any of the variants proposed in the comments above are correct. Can someone explain to me what the purpose of |
OK, to summarize what I've found/been-told (please feel free to correct any of this if it's not right) the purpose is mainly (only?) getting a string to pass to |
I have updated the patch to only use the fallback when the interpreter contains the string "ld-musl-", and will also honor the correct |
8e0ebcd
to
64272fe
Compare
As @richfelker mentions, there is no meaningful way to ever use I think we could have a cleaner solution/workaround if we solve https://bugs.python.org/issue43112 first, which would allow us to detect/set musl at compile time. |
I rebased and did Updated commit is found: ncopa@cec86ae |
Python project requests that PRs don’t use rebase to avoid the bad github UX: https://devguide.python.org/pullrequest/ |
Oh, the PR is squashed when its merged... Sorry. |
@merwok I rebased it again because there was some issues with github yesterday causing the rebase turn into a merge instead. I think should be fixed now and we do no more rebases. Sorry again. I changed two excepts to be clause specific, not only the one you pointed out. Thanks! |
I don’t have much to add. Reading the whole logic gives me multiple OMG WHY moments, but assuming “make |
TBH I'd prefer to have the entire It should give same result as on a glibc based system. The only difference I am aware of is that a 32 bit python on a 64 bit multiarch glibc system may give you the 64 bit library - which of course is wrong. On a musl system this wouldn't happen (I think). Thank you for reviewing it and I hope it didn't give you any nightmares |
@ncopa Is there any chance you could rebase this? Thank you! |
I can rebase. Can I do it with autoconf 2.71 or do I need set up an environment with autoconf 2.69? Line 3 in cbdeda8
|
The autoconf version should not change, and to make this convenient @tiran made an autoconf docker image that can be used. |
Musl libc does not use any ld.cache and `ldconfig -r` does not work with musl. It is also common that musl based container runtimes excludes objdump, gcc and ld, which means that find_library() does not work at all. So as a last resort, if none of the previously mentioned methods works, scan LD_LIBRARY_PATH and some standard locations for elf files that matches the specified name, in a similar way that ld does. We also update the tests so they work as expected with musl libc, which does not have a separate libm or libcrypt. Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Reminder that Python PR process requests no force pushes |
Sorry, forgot that. |
Musl libc does not use any ld.cache and
ldconfig -r
does not work withmusl. It is also common that musl based container runtimes excludes
objdump, gcc and ld, which means that find_library() does not work at
all.
So as a last resort, if none of the previously mentioned methods works,
scan LD_LIBRARY_PATH and some standard locations for elf files that
matches the specified name, in a similar way that ld does.
We also update the tests so they work as expected with musl libc, which
does not have a separate libm or libcrypt.
Signed-off-by: Natanael Copa ncopa@alpinelinux.org
https://bugs.python.org/issue21622