2016-06-17 13 views
1

Ich habe einen Wrapper für eine Socket-API, die ich vor meiner Anwendung mit LD_PRELOAD geladen. Wenn ich jedoch meine .so-Wrapper-Bibliothek mit g ++ kompiliere, funktioniert sie nicht, d. H. Die glibc-Version der Socket-Implementierung wird stattdessen eingefügt.LD_PRELOAD compile.so mit gcc oder g ++

Dies ist, wie ich den Wrapper .so-Bibliothek (eine davon) kompilieren:

gcc -Wall -fPIC -shared socket_hooks.c -o socket_hooks.so 
or 
g++ -Wall -fPIC -shared socket_hooks.c -o socket_hooks.so 

Dies ist, wie ich kompilieren und meine udp-Client ausführen:

g++ -Wall udp_client.cpp -o udp_client 
LD_PRELOAD=./socket_hooks.so ./udp_client 

Nun, wenn ich debug aktivieren (Export LD_DEBUG = alle) und laufen mit .so kompiliert mit gcc (Arbeitsversion) kompilierte Beispiel sehe ich:

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] 

Wenn ich kompilieren .so mit g ++ ich folgendes sehen:

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 beiden Fällen „socket“ Symbol gefunden wird, aber in diesem Fall ist es nicht aufhob, sondern libc stattdessen verwendet wird.

Können Sie erklären, was hier passiert?

+1

Zeigen 'objdump -T socket_hooks.so' oder' nm -D socket_hooks.so'. Ich denke, dass Funktionsnamen in C++ verfälscht sind, also müssen Sie Ihre Funktionen als "extern" C "" deklarieren. –

+0

Danke, das war genau das Problem! – kirbo

Antwort

1

Wenn Sie Ihr Modul mit C++ - Compiler kompilieren, werden Ihre Symbole umbenannt, um das Überladen von Funktionen zu unterstützen. Beispiel: socket kann in _Z10socketiii umgewandelt werden. Deshalb findet Runtime Loader es nicht - es sucht nach socket, nicht _Z10socketiii.

Um Namen Mangeln zu deaktivieren, müssen Sie Ihre Funktionen mit C-Bindung erklären extern "C" verwenden, wahrscheinlich mit Verbindung mit __cplusplus Makro, um mit C-Compiler kompatibel zu bleiben:

#ifdef __cplusplus 
extern "C" { 
#endif 

int socket(int domain, int type, int protocol); 

#ifdef __cplusplus 
} 
#endif 

Alternativ setzen Gestänge auf Symbolbasis:

#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);