OS X での動的シンボル バインドに関して、非常に奇妙な状況が発生しました。解決方法の手がかりを得たいと思っています。
dlopen()
実行時にモジュールを動的にロードするために使用する、C で記述されたアプリケーションがあります。これらのモジュールの一部は、グローバル シンボルをエクスポートします。これは、後でロードされる他のモジュールで使用される可能性があります。
weird_module.so
グローバル シンボルをエクスポートする 1 つのモジュール (これを と呼びます) があり、その 1 つが ですweird_module_function
。odd_module.so が特定のライブラリ (これを と呼びますlibsomething.dylib
) にリンクされた場合、weird_module_function
バインドできません。-lsomething
しかし、 when linkingを削除するとweird_module.so
、 にバインドできweird_module_function
ます。
シンボルをエクスポートしないlibsomething.dylib
原因となる可能性があるのは何ですか? シンボルがエクスポートされる方法をデバッグするためにできることはありますか (シンボルがバインドされる方法をデバッグするためにweird_module.so
使用できる方法と同様)?DYLD_PRINT_BINDINGS
$ LDFLAGS="-bundle -mmacosx-version-min=10.6 -Xlinker -undefined -Xlinker dynamic_lookup /usr/lib/bundle1.o"
$ gcc -o weird_module.so ${LDFLAGS} weird_module.o -lsomething
$ nm weird_module.so | grep '_weird_module_function$'
00000000000026d0 T _weird_module_function
$ gcc -o other_module.so ${LDFLAGS} other_module.o -lsomething
$ nm other_module.so | grep '_weird_module_function$'
U _weird_module_function
$ run-app
Loading weird_module.so
Loading other_module.so
dyld: lazy symbol binding failed: Symbol not found: _weird_module_function
Referenced from: other_module.so
Expected in: flat namespace
dyld: Symbol not found: _weird_module_function
Referenced from: other_module.so
Expected in: flat namespace
# Now relink without -lsomething
$ gcc -o weird_module.so ${LDFLAGS} weird_module.o
$ nm weird_module.so | grep '_weird_module_function$'
00000000000026d0 T _weird_module_function
$ run-app
Loading weird_module.so
Loading other_module.so
# No error!
編集:
問題を再現するために最小限のアプリをまとめてみましたが、その過程で、少なくとも私たちが間違っていたことが1つわかりました. 問題の重複に関連する関連事実が他に 2 つあります。
1 つ目はrun-app
、モジュールをプリロードしてRTLD_LAZY | RTLD_LOCAL
そのメタデータを検査することです。モジュールは、メタデータに応じてまたはのdlclose()
いずれかで編集され、再度開かれます。(問題の両方のモジュールについて、 で再度開きます)。RTLD_LAZY | RTLD_GLOBAL
RTLD_NOW | RTLD_LOCAL
RTLD_LAZY | RTLD_GLOBAL
weird_module.so
次に、グローバル内およびグローバルlibsomething.dylib
に対してシンボルの衝突が発生することが判明しましたconst
。
$ nm weird_module.so | grep '_something_global`
00000000000158f0 S _something_global
$ nm libsomething.dylib | grep '_something_global'
0000000000031130 S _something_global
重複したシンボルが私を未定義の動作の領域に置くことを考慮しても構わないと思っているので、質問を落とします。