2016-04-18 4 views
14

-fvisibility*フラグまたは可視性pragmaおよび__attribute__で定義されているシンボルの可視性には、正確には-rdynamic(または--export-dynamic)が関係しますか?言及ld(1)--export-dynamicについては`-rdynamic`は正確に何を行い、正確に何が必要なのでしょうか?

、:

を... あなたが戻っ プログラムによって定義されたシンボルへの参照する必要がある動的オブジェクトではなく、いくつかの他の動的にロードするために「dlopenを」を使用している場合 オブジェクトの場合、プログラム自体をリンクするときにこのオプションを使用するには、おそらく が必要です。 ...

私は、私は完全にこのことを理解していません。 -rdynamicなしでは動作しない例を教えてください。

編集: 私は実際に、とと-rdynamicせずに、ダミー・ライブラリー(単一ファイル、複数ファイル、様々な-Oレベル、いくつかの間の関数呼び出し、いくつかの隠された記号、いくつかの目に見える)のカップルをコンパイルしてみました今のところ私はバイト一致のの出力を得ています(他のすべてのフラグを一定に保っている場合)。これは非常に困惑しています。

答えて

16

ここでは、-rdynamicの使用方法を示す簡単なプロジェクト例を示します。

bar.cに

extern void foo(void); 

void bar(void) 
{ 
    foo(); 
} 

main.cの

#include <dlfcn.h> 
#include <stdio.h> 
#include <stdlib.h> 

void foo(void) 
{ 
    puts("Hello world"); 
} 

int main(void) 
{ 
    void * dlh = dlopen("./libbar.so", RTLD_NOW); 
    if (!dlh) { 
     fprintf(stderr, "%s\n", dlerror()); 
     exit(EXIT_FAILURE); 
    } 
    void (*bar)(void) = dlsym(dlh,"bar"); 
    if (!bar) { 
     fprintf(stderr, "%s\n", dlerror()); 
     exit(EXIT_FAILURE); 
    } 
    bar(); 
    return 0; 
} 

のMakefile

.PHONY: all clean test 

LDEXTRAFLAGS ?= 

all: prog 

bar.o: bar.c 
    gcc -c -Wall -fpic -o [email protected] $< 

libbar.so: bar.o 
    gcc -shared -o [email protected] $< 

main.o: main.c 
    gcc -c -Wall -o [email protected] $< 

prog: main.o | libbar.so 
    gcc $(LDEXTRAFLAGS) -o [email protected] $< -L. -lbar -ldl 

clean: 
    rm -f *.o *.so prog 

test: prog 
    ./$< 
ここ

bar.cこと共有ライブラリlibbar.somain.cdlopenlibbarて、そのライブラリーからbar()を呼び出すプログラムとなっています。 bar()foo()と呼ばれ、bar.cの外部にあり、main.cで定義されています。 -rdynamicなしだから、

、:

$ make test 
gcc -c -Wall -o main.o main.c 
gcc -c -Wall -fpic -o bar.o bar.c 
gcc -shared -o libbar.so bar.o 
gcc -o prog main.o -L. -lbar -ldl 
./prog 
./libbar.so: undefined symbol: foo 
Makefile:23: recipe for target 'test' failed 

そして-rdynamicと:

$ make clean 
rm -f *.o *.so prog 
$ make test LDEXTRAFLAGS=-rdynamic 
gcc -c -Wall -o main.o main.c 
gcc -c -Wall -fpic -o bar.o bar.c 
gcc -shared -o libbar.so bar.o 
gcc -rdynamic -o prog main.o -L. -lbar -ldl 
./prog 
Hello world 
+0

この例では、マンページの意味を完全に明確にしています。どうもありがとう! – PSkocik

2

私はlibcののバックトレース()/ backtrace_symbols()を使用してバックトレースをプリントアウトするrdynamic使用。

rdynamicを使用しないと、関数名を取得できません。

backtrace()の詳細については、こちらをご覧ください。 https://www.gnu.org/software/libc/manual/html_node/Backtraces.html

関連する問題