Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static library loaded twice

I have shared object A.so which statically links to libssl.a & another shared object B.so which also statically links libssl.a .

A.so & B.so has symbols from libssl.a in GLOBAL scope. I checked this by readelf -s A.so

I have an executable a.out which loads A.so and B.so. When a.out terminated I get a double free error in one of the symbols from libssl.a in A.so.

Even though libssl.a is statically linked to each shared object, since they are exposed globally is it possible that the same symbol is shared instead of picking it's local copy.

What is the workaround this ? How to make the symbols local here ?

Please help

like image 391
KodeWarrior Avatar asked Jun 12 '12 22:06

KodeWarrior


People also ask

What is static library in c++?

A static library (also known as an archive) consists of routines that are compiled and linked directly into your program. When you compile a program that uses a static library, all the functionality of the static library that your program uses becomes part of your executable.

Can a static library depend on another static library?

Static libraries are just archives of object ( .o ) files, so you can't have embedded dependency information.


1 Answers

This is indeed expected. One instance of libssl.a interposes (likely a subset of) the other, and the results are not pretty. You can use a version script (--version-script to ld, with -Wl, for cc) to control what is exported from A.so and B.so. If something is not exported, it cannot be interposed either.

Alternatively, you could compile libssl.a with visibility flags like -fvisibility=hidden. These flags only affect the dynamic linker and not static linking. You likely needed to compile it yourself anyway because shipped .a files tend to contain position-dependent code, meant for linking into executables. Only some platforms such as 32-bit x86 let you get away with linking such code into shared objects and only at the cost of text relocations.

The dlopen with RTLD_LOCAL as suggested in a comment should also work but it seems hackish to use dlopen for this purpose.

Another option is to use the same shared libssl.so in both libraries.

like image 98
jilles Avatar answered Oct 26 '22 07:10

jilles