3

I've struggled with dlopen and undefined symbols.

What I have and tried so far:

libraryA.a with function functionA()

libraryA.so with function functionA()

libraryB.so which is using functionA()

an executable which loads libraryB.so with dlopen.

What I got is:

undefined symbol: functionA

How I build:

libraryA:

gcc -std=gnu11 -O2 -g -Wall -Wstack-usage=2000 -Werror
-fdiagnostics-color -fPIC -pipe -fsigned-char -fno-asynchronous-unwind-tables      
-fno-stack-protector -I../include/ libraryA.c -shared -o libraryA.so

libraryB:

gcc -std=gnu11 -O2 -g -Wall -Wstack-usage=2000 -Werror -fdiagnostics-color 
-fPIC -pipe -fsigned-char -fno-asynchronous-unwind-tables 
-fno-stack-protector -I../include/ libraryB.c -shared -o libraryB.so

Build executable:

-std=gnu99 -pipe -fno-strict-aliasing -fsigned-char -fno-asynchronous-unwind-tables
-fno-stack-protector -Wall -Wextra -Wundef -Wno-sign-compare -Wno-unused-parameter
-Wno-packed-bitfield-compat -Wno-misleading-indentation -fomit-frame-pointer
-maccumulate-outgoing-args -fPIC -m64 -g3 -gdwarf-2 -fno-common -Wstrict-prototypes
-Wimplicit -Wno-pointer-sign -c executable.c -o executable libraryA.a

Open libraryB in executable like this here:

void *handle = dlopen("libraryB.so", RTLD_LAZY);

if (handle == NULL) {
    fprintf( stderr, "Load error (%s)!\n", dlerror());
    return NULL;
}

How can I fix this behavior? I also tried the flag -rdynamic without success. I also tried different dlopen flags but also without success.

Can anyone please help me?

t0mm13b
  • 34,087
  • 8
  • 78
  • 110
Elec
  • 53
  • 1
  • 7

3 Answers3

1

You need to link libraryB.so with libraryA.so since libraryB.so uses a symbol from libraryA.so.

Just add libraryA.so to libraryB.so's link command.

Depending on where the libraries are installed you may also need to use the -rpath flag.

Also, since libraryB.so is dependent on libraryA.so, your Makefile rules should explicitly specify this dependency.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • This I also tried with the **-L** and **-l** option, but I still have the undefined symbol in **libraryB** – Elec Dec 02 '16 at 13:29
  • Still unresolved. `gcc -std=gnu11 -O2 -g -Wall -Wstack-usage=2000 -Werror -fdiagnostics-color -fPIC -pipe -fsigned-char -fno-asynchronous-unwind-tables -fno-stack-protector -I../include/ libraryA.so libraryB.c -shared -o libraryB.so` – Elec Dec 02 '16 at 13:37
  • 1) Use `objdump -T` to verify that the symbol referenced from libraryB.so is identical to the symbol declared in libraryA.so, and the libraryA.so symbol is declared as global 2) Use `objdump -x` to verify that `libraryb.so` specifies "NEEDED libraryA.so` – Sam Varshavchik Dec 02 '16 at 13:44
  • 1) libraryA.so `00000000001d7d3b g DF .text 000000000000008d Base functionA` libraryB.so `0000000000000000 DF *UND* 0000000000000000 functionA` 2) libraryB.so show no specified libraryA.so Do I something wrong? – Elec Dec 02 '16 at 13:50
  • Try putting libraryA.so _after_ libraryB.c (see [creating-a-shared-object-which-depends-on-other-shared-objects](http://stackoverflow.com/questions/40780247/creating-a-shared-object-which-depends-on-other-shared-objects) for background). – yugr Dec 02 '16 at 14:55
  • I've tried this out but the functionA() is still unresolved. `gcc -std=gnu11 -O2 -g -Wall -Wstack-usage=2000 -Werror -fdiagnostics-color -fPIC -pipe -fsigned-char -fno-asynchronous-unwind-tables -fno-stack-protector -I../include/ libraryB.c libraryA.so -shared -o libraryB.so ` nm -g libraryB() `U functionA()` – Elec Dec 05 '16 at 10:04
0

When you build Library B, you need to link it against Library A:

gcc -shared -o libraryB.so libraryB.c -lraryA

You might need to add a suitable -L option if libraryA.so isn't already on your search path.

If Library B is intended to be complete, with no undefined symbols, add the option -Wl,--no-undefined to your link line. That way, any missing dependencies will be reported at link time, rather than waiting until run-time.

Otherwise, you may still examine libarryB.so with ldd to see which libraries it references.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
-1

Solution

gcc -std=gnu11 -O2 -g -Wall -Wstack-usage=2000 -Werror -fdiagnostics-color -fPIC -pipe -fsigned-char -fno-asynchronous-unwind-tables -fno-stack-protector -I../include/ libraryB.c libraryA_static.a -shared -o libraryB.so

I build my libraryB with the static library of A and after that everything is fine and I can use all symbols and functions.

Many thanks to all of you!

Elec
  • 53
  • 1
  • 7
  • That's not the same, though - you've now linked B *statically* against A. You should be able to link B *dynamically* against A so they can be updated independently. Something like `gcc -shared -o libraryB.so libraryB.c -lraryA`. Add `-Wl,--no-undefined` if you want to be sure that all of B's requirements are satisfied. – Toby Speight Dec 05 '16 at 11:12