I reduced my problem using below test codes,
main.cc
#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);
}
Compiled 1.cc into a lib1.so and 2.cc into lib2.so like below,
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.
Above steps will produce lib1.so, lib2.so and a.out. The problem here is while running the executable a.out, it is unable to lookup the original "fread" symbol when using dlsym(RTLD_NEXT).
The output is,
arunprasadr@demo:~/works/myex/c++/rtdl_next$ LD_LIBRARY_PATH=./ ./a.out
init1: fopen addr:0
init2 called
But if the change the link process of lib2.so(like below), it seems to be working
g++ 2.cc -shared -ldl -fvisibility=default -fPIC -o lib2.so -L.
g++ main.cc -l2 -l1 -L.
LD_LIBRARY_PATH=./ ./a.out
output:
arunprasadr@demo:~/works/myex/c++/rtdl_next$ LD_LIBRARY_PATH=./ ./a.out
init1: fopen addr:0x7f9e84a9e2c0
init2 called
Can anyone please explain what is happening in the background? Thanks in advance.