0

I am getting an undesired loading of a shared library which has already been loaded.

I have a binary(test_bin) which is supposed to load a shared library(libtest.so). Also, I have a C python extension module(extension.so) which also loads libtest.so

Now, when I start the binary with an embedded python interpreter and import the extension module, I get a lot of errors happening due to the static globals in the library getting initialized twice.

My question is, in this case why is libtest.so loaded during the extension import even though it has already been loaded by the binary(have confirmed this with lsof)

Note: The version, name and location of the shared library used by the binary and the python extension are all same(verified by ldd)

Invocation:

./test_bin
In [1]: from some.location import extension
    # errors due to double initialization

Please let me know if you need any other information

  • perhaps your libtest.so is position-independent (compiled as gcc -fPIC), then I think it can be loaded twice – user1514631 Oct 21 '15 at 12:11
  • Yes it is PIC. I think we need position independent code for making a shared library, don't we? – Kanishka Khandelwal Oct 21 '15 at 12:12
  • Please note that the library is also created by me so any help to create it in a way which solves the problem would be appreciated. – Kanishka Khandelwal Oct 21 '15 at 12:14
  • @KanishkaKhandelwal it depends what you mean by *shared library*. – Peter Wood Oct 21 '15 at 12:21
  • @PeterWood By shared library I mean a library which is dynamically loadable. In this case, my library is only to be used in these 2 cases(to be dynamically loaded by the binary and by the extension module). Note that the extension module can also be imported without being embedded by the binary. So, do you have any suggestions here? – Kanishka Khandelwal Oct 21 '15 at 12:26
  • @KanishkaKhandelwal, as far as I know PIC is not the same as a relocatable shared object. my recommendation is to try to compile your so without -fPIC and see if it works – user1514631 Oct 21 '15 at 12:54
  • @user1514631 I tried building the library without PIC but it didn't change anything. Please note that the object files constituting the library are still compiled with PIC(which I suspect we have to). – Kanishka Khandelwal Oct 21 '15 at 13:06
  • @KanishkaKhandelwal, please note that currently i can't experiment with the options, but I'm pretty sure that the -fPIC option is not mandatory for shared libs (after all it's a command-line argument which you can omit). PIC would be "mandatory" on an architecture without MMU and where the loader doesn't relocate, but this is clearly not the case. If you have complete control over the libtest.so, remove the -fPIC option from the makefile, for both compiling and linking and see if it helps. – user1514631 Oct 21 '15 at 13:19
  • @user1514631 I have indeed removed the -fPIC option while creating the shared library `gcc -shared -m64 $(SHARED_OBJS) -o libtest.so` . But. the object files need to be compiled with -fPIC in order to create the library using -shared option, right? removing that gives this error: `.rodata' can not be used when making a shared object; recompile with -fPIC – Kanishka Khandelwal Oct 21 '15 at 13:42
  • Having the same shared library link with both the executable and the extension should not cause problem. See for example this [small complete example](https://gist.github.com/sterin/63f661e46cbee6bafdff). Please provide more details (OS, version, architecture) and a small complete example that reproduces the problem. – sterin Oct 23 '15 at 06:13
  • Have you tried using `-rdynamic` to compile/link the binary? That way the shared library loaded from the executable should be visible to the shared libraries, preventing the double load. – user4815162342 Oct 24 '15 at 18:20

0 Answers0