Compile C program with dlopen and dlsym with -fPIC

I have a problem with the wrong character resolution. My main program loads a shared library with dlopen and a character from it with dlsym. Both the program and the library are written in C. Library code

int a(int b) { return b+1; } int c(int d) { return a(d)+1; } 

To make it work on a 64-bit machine, -fPIC is passed to gcc during compilation.

Program:

 #include <dlfcn.h> #include <stdio.h> int (*a)(int b); int (*c)(int d); int main() { void* lib=dlopen("./libtest.so",RTLD_LAZY); a=dlsym(lib,"a"); c=dlsym(lib,"c"); int d = c(6); int b = a(5); printf("b is %dd is %d\n",b,d); return 0; } 

Everything works fine if the program is NOT compiled with -fPIC, but if the program fails with -fPIC, it crashes with a segmentation error. The study showed that the accident was caused by incorrect resolution of the a symbol. A crash occurs when a is called, regardless of whether it is from a library or the main program (the latter is obtained by commenting out the line that calls c () in the main program).

Calling c () does not cause any problems, perhaps because c () is not internally called by the library itself, and a () is both a function used inside the library and a library API function.

A simple workaround is not to use -fPIC when compiling the program. But this is not always possible, for example, when the code of the main program should be in the most common library. Another workaround is to rename the pointer to function a to something else. But I can not find any real solution.

Replacing RTLD_LAZY with RTLD_NOW does not help.

+5
c gcc linux elf dlopen
source share
2 answers

I suspect there is a collision between two global symbols. One solution is to declare a in the main program as static. Alternatively, the linux man page mentions the RTLD_DEEPBIND flag, a Linux-only extension that you can pass to dlopen , and this will cause the library to prefer its own characters over global characters.

+2
source share

It seems that this problem can happen in one more case (for example, for me). I have a program and several dynamically linked libraries. And when I tried to add another one, I used a function from a static lib (also mine). And I forgot to add this static lib to the list of links. Linker did not warn me about this, but the program distorted the segmentation error.

Perhaps this will help someone.

0
source share

All Articles