Что именно делает "- rdynamic " и когда именно это необходимо?
что именно -rdynamic
(или --export-dynamic
на уровне компоновщика) и как это связано с видимостью символа, определенной -fvisibility*
флаги или видимость pragma
s и __attribute__
s?
на --export-dynamic
, ld (1) отмечает:
... Если вы используете "dlopen" для загрузки динамического объекта, который должен ссылаться назад к символам, определенным программой, а не к некоторым другим динамическим объект, тогда вам, вероятно, понадобится использовать это вариантом при компоновке программы. ...
Я не уверен, что полностью понимаю это. Не могли бы вы привести пример, который не работает без -rdynamic
но не с ним?
редактировать:
Я действительно попытался скомпилировать пару фиктивных библиотек (один файл, много файлов, различные уровни-O, некоторые межфункциональные вызовы, некоторые скрытые символы, некоторые видимые), с и без -rdynamic
и до сих пор я получаю байт-идентичны выходы (при сохранении всех других флагов постоянными, конечно), что довольно озадачивает.
2 ответов
вот простой пример проекта, чтобы проиллюстрировать использование -rdynamic
.
бар.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;
}
make-файл
.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
будет
программы dlopen
s 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 для печати обратных следов с помощью backtrace()
/backtrace_symbols()
из Glibc.
без -rdynamic
, вы не можете получить имена функций.
чтобы узнать больше об backtrace()
читаем здесь.