`-rdynamic’究竟做了什么以及何时需要它?

-rdynamic (或--export-dynamic器级别的--export-dynamic )究竟做了什么以及它如何与-fvisibility* flags或visibility pragma s和__attribute__ s定义的符号可见性相关?

对于--export-dynamic , ld(1)提到:

…如果使用“dlopen”加载需要引用程序定义的符号的动态对象,而不是某些其他动态对象,则在链接程序本身时可能需要使用此选项。 …

我不确定我完全明白这一点。 你能否提供一个例子,如果没有-rdynamic ,它会不起作用,但是呢?

编辑 :我实际上尝试编译了几个虚拟库(单个文件,多个文件,各种-O级别,一些函数间调用,一些隐藏符号,一些可见),有和没有-rdynamic ,到目前为止我已经得到字节相同的输出(当然保持所有其他标志不变),这是非常令人费解的。

这是一个简单的示例项目,用于说明-rdynamic的使用。

bar.c

 extern void foo(void); void bar(void) { foo(); } 

main.c中

 #include  #include  #include  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 $@ $< libbar.so: bar.o gcc -shared -o $@ $< main.o: main.c gcc -c -Wall -o $@ $< prog: main.o | libbar.so gcc $(LDEXTRAFLAGS) -o $@ $< -L. -lbar -ldl clean: rm -f *.o *.so prog test: prog ./$< 

在这里, bar.c成为一个共享库libbar.somain.c成为一个程序,它可以从该库中调用libbar并调用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 

我使用rdynamic使用Glibc的backtrace() / backtrace_symbols()打印出回溯。

如果没有-rdynamic ,则无法获取函数名称。

要了解有关backtrace()更多信息,请在此处阅读。