7

I'm using dlopen to load a shared library at run time

dlopen("SharedLibarary1.so", RTLD_NOW | RTLD_GLOBAL);

In that shared object I refer to a const char* defined in another shared library "SharedLibarary2.so".

The Executable, and both the libraries are built using -rdynamic.

But I still get the run time error when using dlopen: "/usr/lib/SharedLibarary1.so: undefined symbol" and points to the mangled const char* has the undefined symbol.

Whith GDB "info share" I can see that the second library is not loaded at the point of the error.

How ever that problem goes away if I do a dlopen on the second library before I do on the first library.

Is there a better way to force the loader to load the second library for the unresolved symbol?

Sam Miller
  • 23,808
  • 4
  • 67
  • 87
Sak
  • 269
  • 1
  • 4
  • 13
  • 1
    yes. Don't make the library you load rely on something that will only be linked in by another library that you will load using dlopen(). Use a shared object that is loaded the regular way that has that symbol. Does using RTLD_LAZY help by the way? – CashCow Oct 19 '12 at 13:56

2 Answers2

8

When building a shared library, you can link another inside, e.g. like

 gcc -shared -rdynamic lib1*.pic.o -lshared2 -o SharedLibrary1.so  

Then check with ldd SharedLibrary1.so

(look e.g. at the output of ldd on your system's libgtk-3.so.0 for an example)

% ldd /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
linux-vdso.so.1 =>  (0x00007fff6afff000)
libgdk-3.so.0 => /usr/lib/x86_64-linux-gnu/libgdk-3.so.0 (0x00007f0572628000)
libgmodule-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 (0x00007f0572424000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f057221b000)
libpangocairo-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 (0x00007f057200e000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f0571cd2000)
libXi.so.6 => /usr/lib/x86_64-linux-gnu/libXi.so.6 (0x00007f0571ac2000)
libXcomposite.so.1 => /usr/lib/x86_64-linux-gnu/libXcomposite.so.1 (0x00007f05718c0000)
libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f05716be000)
libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f05714b7000)
libatk-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libatk-1.0.so.0 (0x00007f0571294000)
libcairo-gobject.so.2 => /usr/lib/x86_64-linux-gnu/libcairo-gobject.so.2 (0x00007f057108b000)
libcairo.so.2 => /usr/lib/x86_64-linux-gnu/libcairo.so.2 (0x00007f0570d91000)
libgdk_pixbuf-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0 (0x00007f0570b71000)
libpangoft2-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0 (0x00007f0570946000)
libpango-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 (0x00007f05706f8000)
libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f0570459000)
libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f0570222000)
libgio-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0 (0x00007f056fece000)
libgobject-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 (0x00007f056fc7e000)
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f056f986000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f056f703000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f056f4e7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f056f160000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f056ef4c000)
libXinerama.so.1 => /usr/lib/x86_64-linux-gnu/libXinerama.so.1 (0x00007f056ed4a000)
libXrandr.so.2 => /usr/lib/x86_64-linux-gnu/libXrandr.so.2 (0x00007f056eb42000)
libXcursor.so.1 => /usr/lib/x86_64-linux-gnu/libXcursor.so.1 (0x00007f056e937000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f056e733000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0572f57000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f056e512000)
libpixman-1.so.0 => /usr/lib/x86_64-linux-gnu/libpixman-1.so.0 (0x00007f056e28c000)
libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f056e064000)
libxcb-shm.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0 (0x00007f056de61000)
libxcb-render.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-render.so.0 (0x00007f056dc57000)
libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007f056da4d000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f056d836000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f056d60b000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f056d3eb000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f056d1d5000)
libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007f056cfd2000)
libffi.so.5 => /usr/lib/x86_64-linux-gnu/libffi.so.5 (0x00007f056cdc5000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f056cb87000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f056c983000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f056c77e000)
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Fixed. Adding SharedLibrary2.la as part of SharedLibrary1 LIBADD in makefile.am creates the dependency and links to it. – Sak Oct 19 '12 at 15:37
2

If possible, you should link each shared library you dlopen() with the linker arguments to force it to resolve all it's symbols when the library is created. This way you can be more sure that you know where all your symbols will be coming from. ("-z defs" for example, under Linux x86)

That way, if you add a new source file, but forget to add the object to the link, you won't be scratching your head because of a runtime error from dlopen/dlsym.

Robert Boehne
  • 271
  • 3
  • 11