`-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.so
和main.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()
更多信息,请在此处阅读。