-rdynamic
(またはリンカーレベルで--export-dynamic
)が正確に行うことと、-fvisibility*
フラグまたは可視性pragma
sおよび__attribute__
s?
--export-dynamic
の場合、 ld(1) 言及:
...「dlopen」を使用して、他の動的オブジェクトではなく、プログラムで定義されたシンボルを参照する必要がある動的オブジェクトをロードする場合、おそらくプログラム自体をリンクするときにこのオプションを使用する必要があります。 ...
私はこれを完全に理解しているかどうかはわかりません。 -rdynamic
なしでは機能しないが、それで機能する例を提供してください。
Edit:実際にいくつかのダミーライブラリ(シングルファイル、マルチファイル、さまざまな-Oレベル、いくつかの関数間呼び出し、いくつかの非表示)をコンパイルしようとしましたシンボル、いくつかは可視)、-rdynamic
の有無にかかわらず、これまでのところbyte-identical出力(他のすべてを保持する場合)フラグ定数はもちろん)、これは非常に不可解です。
_-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;
}
_
メイクファイル
_.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
_
Glibcのbacktrace()
/backtrace_symbols()
を使用して、rdynamicを使用してバックトレースを出力します。
_-rdynamic
_がないと、関数名を取得できません。
backtrace()
の詳細については、 here をお読みください。