2016-06-17 4 views
1

私はアプリケーションの前にLD_PRELOADを使用してプリロードするソケットAPIのラッパーを用意しています。しかし、g ++を使って自分の.soラッパーライブラリをコンパイルすると、うまくいかない、つまりglibc版のソケット実装が代わりにピックアップされます。LD_PRELOAD gccまたはg ++を使用して.soをコンパイルします

これは私がラッパーの.soライブラリ(これらのいずれか)をコンパイルする方法である:私はデバッグを有効にすると

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

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

これは私が私のUDPクライアントをコンパイルして実行する方法ですgccの(作業バージョン)コンパイルの例を使用してコンパイル(輸出LD_DEBUG =全て)との.soで実行私は、次を参照してください。

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] 

IはG ++を使用.SOコンパイルすると、私は次を参照してください。両方の場合において

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] 

「ソケット」シンボルが検出されたが、後者の場合には、ピックアップされず、libcの代わりに使用されています。

ここで何が起こっているのか説明できますか?

+1

'objdump -T socket_hooks.so'または' nm -D socket_hooks.so'を表示します。私は、関数名がC++でmangledされていると思いますので、関数を 'extern" C "'として宣言する必要があります。 –

+0

ありがとう、それはまさに問題でした! – kirbo

答えて

1

C++コンパイラを使用してモジュールをコンパイルすると、関数オーバーロードをサポートするためにシンボルが名前変更されます。たとえば、socket_Z10socketiiiに変換されます。そのため、ランタイムローダーはそれを見つけられません - それはsocketであり、_Z10socketiiiではありません。

名前の符号化をディセーブルにするためには、あなたがCコンパイラとの互換性を保つためには、おそらくマクロ__cplusplusと併せて、extern "C"を使用してCリンケージを使用して関数を宣言する必要があります。また

#ifdef __cplusplus 
extern "C" { 
#endif 

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

#ifdef __cplusplus 
} 
#endif 

、リンクを設定します

#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); 
関連する問題