使用dlopen编译C程序和-fPIC对dlsym [英] Compile C program using dlopen and dlsym with -fPIC
问题描述
我有一个关于一个错误的符号解析问题。我的主要程序加载使用dlopen的共享库,并从它的dlsym的象征。无论是程序和库是用C编写
库code
I am having a problem about a wrong symbol resolution. My main program loads a shared library with dlopen and a symbol 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;
}
为了使其在64位机器上工作,-fPIC传递编译时与gcc。
In order to make it work on a 64-bit machine, -fPIC is passed to gcc when compiling.
该计划是:
#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 %d d is %d\n",b,d);
return 0;
}
一切都正常运行,如果该程序不-fPIC编译,但是它与分段故障崩溃时,程序与-fPIC编译。经过调查,发现,坠机是由于符号的错误的决议。当被调用时,无论从库中或主程序(后者被注释掉调用C()在主程序行获得)发生崩溃。
Everything runs fine if the program is NOT compiled with -fPIC, but it crashes with a segmentation fault when the program is compiled with -fPIC. Investigation led to discover that the crash is due to the wrong resolution of symbol a. The crash occurs when a is called, no matter whether from the library or the main program (the latter is obtained by commenting out the line calling c() in the main program).
出现没有问题,可能是因为C()不是由库本身内部调用,而()既是由图书馆和图书馆的API函数内部使用的功能。
No problems occur when calling c() itself, probably because c() is not called internally by the library itself, while a() is both a function used internally by the library and an API function of the library.
编译程序时,一个简单的解决方法是不使用-fPIC。但是,这并不总是可能的,例如,当主程序的code的是在一个共享库本身。另一个解决方法是重命名函数指针一到别的东西。但是,我找不到任何真正的解决办法。
A simple workaround is not use -fPIC when compiling the program. But this is not always possible, for example when the code of the main program has to be in a shared library itself. Another workaround is to rename the pointer to function a to something else. But I cannot find any real solution.
与RTLD_NOW更换RTLD_LAZY于事无补。
Replacing RTLD_LAZY with RTLD_NOW does not help.
推荐答案
我的犯罪嫌疑人的有两个全局符号之间的冲突。一种解决方案是申报 A
在主程序为静态。另外,在Linux手册页中提到 RTLD_DEEPBIND
标记,只有Linux的扩展,它可以传递给的dlopen
键,这将导致库preFER在全局符号自己的符号。
I suspect that there is a clash between two global symbols. One solution is to declare a
in the main program as static. Alternatively, the linux manpage mentions RTLD_DEEPBIND
flag, a linux-only extension, which you can pass to dlopen
and which will cause library to prefer its own symbols over global symbols.
这篇关于使用dlopen编译C程序和-fPIC对dlsym的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!