-
Notifications
You must be signed in to change notification settings - Fork 24
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
Using different versions of the same library simultaneously ? #393
Comments
I think some (short as possible) instructions on how to reproduce this would help. The Perl code itself looks fine to me. The FFI::Platypus::DL interface is a pretty thin layer over the Unix functions (I'm assuming you aren't in Windows since your C++ program was also using dl*, but if you were there is some potential for shenanigans because of the compatibility layer). So I don't expect there to be anything wrong there. https://github.com/PerlFFI/FFI-Platypus/blob/main/xs/DL.xs
The one nit I can thing of is if libtest1 and libtest2 have a dependency on a third library that doesn't get unloaded because it gets linked to Perl or another extension somewhere. |
Yes I'm on Linux. The libraries used in this simple test case are the versions 103.0 and 104.0 of the unitsync library from the SpringRTS project. Steps to reproduce using my code verbatim:
When the lines are commented, the output is: When the lines are uncommented, the output should be the same, but it is actually: If needed, the source code of the unitsync library is available here: v103.0, v104.0. I can also provide the C++ code which works correctly with the two libraries, if needed. Thanks a lot for taking a look at this ! |
Here are the ldd results for the two libraries:
|
As said on IRC, I compared the debug outputs of the linker when using the Perl script (which produces the error) and the C++ program (which works), and I noticed a difference regarding the bindings of this function:
In Perl case libtest2 is bound to the symbol from libtest1 whereas in C++ case both libs bind to libstdc++. So today I tried to run the Perl script with |
The problem seems to be related to the fact that both libtest1 and libtest2 are statically linked to libstdc++6, but the version of this library or the glibc version used aren't necessarily the same... Here is what I think is happening in Perl case after analyzing LD debug outputs:
When I run the C++ program, the libstdc++6 library is already loaded before trying to load libtest1 and libtest2, so both libraries bind to the dynamic library instead of using their local symbols and there is no problem. When I set Out of curiosity I also tried using the Dynamic linker debug traces analysisFor reference, here are the relevant parts of the very verbose LD debug outputs regarding two selected libstdc++6 symbols, which I will just call When the Perl script is executed as this, without any change (i.e. libtest1 is loaded in default mode
In the first two paragraphs we see that libtest1 bindings are using the statically linked code for both symbols as expected. However in the last two paragraphs we see that libtest2 is only using its own symbol for When the Perl script is executed with
The only difference here is that libtest2 is entirely relying on libtest1 for the libstdc++6 symbols, whereas it was mostly using its own statically linked code previously. The Perl script works a bit better but still crashes when trying to actually use the libraries. When the Perl script is executed with
Both libtest1 and libtest2 use the symbols from libstdc++ instead of using their statically linked code. This is not ideal but at least it seems to work. I guess I can add the following two lines of code at the start of my Perl code to use this workaround without relying on if(my $dlHdl=FFI::Platypus::DL::dlopen('libstdc++.so.6',RTLD_PLATYPUS_DEFAULT | RTLD_GLOBAL)) {
FFI::Platypus::DL::dlclose($dlHdl);
} But it would be really better if there was a way to just actually use the static code from the libraries themselves without triggering some weird conflict, especially because some distributions such as Alpine don't provide libstdc++ by default... |
Apparently it is the expected behavior to have only one |
I don't think this is a Platypus bug and unfortunately related to the challenges of loading a C++ library from C program. I suspect that if your C++ program were re-written as C and linked using the C linker that you'd get the same error. I think these are the options:
|
I'm going to tag this as "Documentation" and leave it open because I think a useful FAQ could probably be synthesized from this. Thanks @Yaribz for reporting. Note: I think there is a more generic problem with multiple C++ libs, they don't have to be different versions of the same. |
That's exactly what I wanted to check before closing the issue :)
Indeed, I chose the issue title when I though the problem was related to conflicts involving symbols defined by the libraries themselves, not by their statically linked libstdc++ versions. One question though: when I was investigating the problem I wanted to try the edit: I just tested with |
Yeah I chose to not include that functionality in the |
Yeah true it isn't really Platypus itself, but it is a thing that you can run into when using Platypus which I try to document where possible. |
Hello,
I'm trying to use
FFI::Platypus
to load two libraries, but I encounter weird problems...Both libraries work perfectly through
FFI::Platypus
as long as I don't load the other one. But as soon as I do, it crashes or doesn't produce the expected behavior, depending on which version I load first. I'm not sure whether it is important, but these two libraries have lots of functions with same name (they are actually two versions of the same library, and have the sameSONAME
).I managed to reduce the Perl code triggering the problem to just a few lines:
Here I'm not even trying to use both libraries simultaneously. I just load one, then unload it without using it, and then load and use the second one.
When I try to actually use both libraries, it usually segfaults on exit.
For the record these libraries are used a lot, simultaneously, by other programs which don't encounter this problem. I even made a small C++ program myself which loads them manually with dlopen/dlsym, and it works perfectly. So in C++ I'm able to use both of them simultaneously but in Perl I can't.
I guess I'm doing something wrong in my Perl code but I can't find it, any help would be greatly appreciated !
P.S. the libraries are from the open source SpringRTS project, I can provide them if needed
The text was updated successfully, but these errors were encountered: