我使用下面的测试代码减少了我的问题,
主文件
#include <iostream>
int main(int argc, const char** argv) {
void init2();
init2();
return 0;
}
2.cc
#include <iostream>
int init2() {
void init1();
init1();
std::cout<<"init2 called\n";
return 0;
}
1.cc
#include <dlfcn.h>
#include <pthread.h>
#include <stdio.h>
#include <iostream>
typedef FILE* (*FopenFunction)(const char* path, const char* mode);
static FopenFunction g_libc_fopen = NULL;
void init1() {
g_libc_fopen = reinterpret_cast<FopenFunction>(
dlsym(RTLD_NEXT, "fopen"));
std::cout<<"init1: fopen addr:"<<(void*)g_libc_fopen<<"\n";
}
__attribute__ ((__visibility__("default")))
FILE* fopen_override(const char* path, const char* mode) __asm__ ("fopen");
__attribute__ ((__visibility__("default")))
FILE* fopen_override(const char* path, const char* mode) {
return g_libc_fopen(path, mode);
}
将 1.cc 编译成 lib1.so 并将 2.cc 编译成 lib2.so 如下所示,
g++ 1.cc -shared -ldl -fvisibility=default -fPIC -o lib1.so -L.
g++ 2.cc -shared -ldl -fvisibility=default -fPIC -o lib2.so -l1 -L.
g++ main.cc -l2 -l1 -L.
以上步骤将生成 lib1.so、lib2.so 和 a.out。这里的问题是在运行可执行文件 a.out 时,使用 dlsym(RTLD_NEXT) 时无法查找原始的“fread”符号。
输出是,
arunprasadr@demo:~/works/myex/c++/rtdl_next$ LD_LIBRARY_PATH=./ ./a.out
init1: fopen addr:0
init2 called
但是如果改变 lib2.so 的链接过程(如下所示),它似乎正在工作
g++ 2.cc -shared -ldl -fvisibility=default -fPIC -o lib2.so -L.
g++ main.cc -l2 -l1 -L.
LD_LIBRARY_PATH=./ ./a.out
输出:
arunprasadr@demo:~/works/myex/c++/rtdl_next$ LD_LIBRARY_PATH=./ ./a.out
init1: fopen addr:0x7f9e84a9e2c0
init2 called
谁能解释一下后台发生了什么?提前致谢。