I have a wrapper for a socket API which I preload before my application using LD_PRELOAD. However when I compile my .so wrapper library using g++ it doesn't work, i.e., glibc version of the socket implementation is picketd instead.
This is how I compile the wrapper .so library (one of these):
gcc -Wall -fPIC -shared socket_hooks.c -o socket_hooks.so
or
g++ -Wall -fPIC -shared socket_hooks.c -o socket_hooks.so
This is how I compile and run my udp client:
g++ -Wall udp_client.cpp -o udp_client
LD_PRELOAD=./socket_hooks.so ./udp_client
Now when I enable debug (export LD_DEBUG=all) and run with .so compiled using gcc (working version) compiled example I see:
17278: symbol=socket; lookup in file=./udp_client [0]
17278: symbol=socket; lookup in file=./socket_hooks.so [0]
17278: binding file ./udp_client [0] to ./socket_hooks.so [0]: normal symbol `socket' [GLIBC_2.2.5]
When I compile .so using g++ I see the following:
17285: symbol=socket; lookup in file=./udp_client [0]
17285: symbol=socket; lookup in file=./socket_hooks.so [0]
17285: symbol=socket; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0]
17285: binding file ./udp_client [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `socket' [GLIBC_2.2.5]
In both cases "socket" symbol is found, but in the latter case it is not picked up, but libc is used instead.
Could you explain what is happening here?
When you compile your module with C++ compiler, your symbols are name mangled to support function overloading, for example socket may be transformed to _Z10socketiii. That's why runtime loader doesn't find it - it's looking for socket, not _Z10socketiii.
In order to disable name mangling, you have to declare your functions with C linkage using extern "C", probably with conjunction with __cplusplus macro, in order to stay compatible with C compilers:
#ifdef __cplusplus
extern "C" {
#endif
int socket(int domain, int type, int protocol);
#ifdef __cplusplus
}
#endif
Alternatively, set linkage on per-symbol basis:
#ifdef __cplusplus
#define DONT_MANGLE_ME extern "C"
#else
#define DONT_MANGLE_ME
#endif
DONT_MANGLE_ME int socket(int domain, int type, int protocol);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With