1

(Intel のフォーラムはこの質問をするより自然な場所ですが、Intel の完全な欠如よりも多くの活動を期待してここに投稿しています - これまでのところ)

Intel Media SDK (Linux サーバー) を使用して h264 ビデオを操作するダイナミック リンク ライブラリを作成できず、MFX ライブラリの設計に問題があることに気付きました。私が理解している方法では、プログラムは次のような静的ライブラリにリンクすることになっています。

$ g++ .... -L/opt/intel/mediasdk/lib/lin_x64 -lmfx

ただし、このライブラリはすべての呼び出しをed動的ライブラリlibmfx.aに委譲しているように見えます。静的ライブラリと動的ライブラリによって公開される関数名(およびシグネチャ) は同一であることに注意してください。これは、混乱を招き危険です。dlopen/opt/intel/mediasdk/lib64/libmfxhw64.so

libmfx.a私はこの設計の背後にある理論的根拠を理解していませんが、(静的)が共有オブジェクトに含まれている場合、ライブラリ内からの静的/グローバル初期化が明らかに混乱を引き起こしているということでなければ、それ自体が問題になることはありません。すなわち:

    +------+     +-----------+
    | main | <-- | mylib.so  |
    +------+     |           |          +---------------+
                 | libmfx.a  | (dlopen) | libmfxhw64.so |
                 |          <-------------              |
                 |+---------+|          |+-------------+|
                 ||MFXInit()||          ||  MFXInit()  ||
                 ||...      ||          ||  ...        ||
                 ||         ||          ||             ||
                 +===========+          +===============+

上記のライブラリは、次のように組み立てることができます。

$ g++ -shared -o mylib.so my1.o my2.o -lmfx

そして、(動的に)次main.oのようにリンクされます:

$ g++ -o main main.o mylib.so -ldl

( を許可するには、追加libdlが必要であることに注意してください。)libmfx.adlopen() libmfxhw64.so

残念ながら、最初のMFXInit()呼び出しで、プログラムはセグメンテーション違反 (アドレス 0x0000400 へのアクセス) を引き起こします。GDB バックトレース:

#0  0x0000000000000400 in ?? ()
#1  0x00007ffff61fb4cd in MFXInit () from /opt/intel/mediasdk/lib64/libmfxhw64-p.so.1.13
#2  0x00007ffff7bd3a1f in MFX_DISP_HANDLE::LoadSelectedDLL(char const*, eMfxImplType, int, int) () from ./lib-a.so
#3  0x00007ffff7bd12b1 in MFXInit () from ./lib-a.so
#4  0x00007ffff7bd09c8 in test_mfx () at lib.c:12
#5  0x0000000000400744 in main (argc=1, argv=0x7fffffffe0d8) at main.c:8

( MFXInit()at stackframe#3が in でlibmfx.aあるのに対し、 at#1は inであることに注意してlibmfxhw64.soください。)

をスタティックライブラリとして作成してもクラッシュしないことに注意してください。ブレークポイントと逆アセンブラを使用して、次のバックトレース スナップショットを作成することができました。どちらの場合もは ですが、異なるバージョンのにヒットしているように見えます(絶対アドレスは再配置のために無意味です)。mylib#1MFXInit+424MFXQueryVersion

#0  0x00007ffff6411980 in MFXQueryVersion () from /opt/intel/mediasdk/lib64/libmfxhw64-p.so.1.13
#1  0x00007ffff640c4cd in MFXInit () from /opt/intel/mediasdk/lib64/libmfxhw64-p.so.1.13
#2  0x000000000040484f in MFX_DISP_HANDLE::LoadSelectedDLL(char const*, eMfxImplType, int, int) ()
#3  0x00000000004020e1 in MFXInit ()
#4  0x0000000000401800 in test_mfx () at lib.c:12
#5  0x0000000000401794 in main (argc=1, argv=0x7fffffffe0e8) at main.c:8

静的および共有 Intel ライブラリの両方が同じ API 関数を公開しているため、ガッツに直接リンクできlibmfxhw64.soますが、静的な「ディスパッチャ」をバイパスすることは保証されていないと思います(?)

誰かがその設計の背後にあるインテルの考えを説明できますか? .so仕様、同じインターフェイスを持つにのみ委任する静的ライブラリを提供するのはなぜですか?

また、SEGV は、 または のいずれかの静的/グローバル データによって引き起こされているようlibmfx.aですlibmfxhw64.so。動的にロードされた静的/グローバル セクションで特定の実行順序を強制する方法はありますか? この種の問題をデバッグするための最良のアプローチは何ですか?


Intel Haswell i7-4790 @3.6Ghz 上の Intel Media SDK R2 (ubuntu 12) および Intel Media SDK 2015R3-R5 (Centos 7、1.13/1.15) でテスト済み

Intel MSDK セットアップが機能している場合は、サンプル コードをコンパイルして問題を確認してください。

4

2 に答える 2

3

ディスパッチャ ソース コードの最近のリリースのファイル「readme-dispatcher-linux.pdf」の最後に、次のような記述があります。

実行可能モジュールまたは共有オブジェクトから Dispatcher ライブラリを使用することには、わずかな違いがあります。Linux* でそれ自体と SDK 共有オブジェクトの間のシンボルの競合を軽減するには、アプリケーションは次のことを行う必要があります。

私はこれを使用しましたが、あなたが説明したシンボルの競合の問題に対処するために機能します。

「Intel Media Server Studio Professional 2016」をインストールすると、このファイルを見つけることができます。無料のコミュニティ版があります。ソース ファイルと PDF は /opt/intel/mediasdk/opensource/ にあります。

于 2016-07-31T20:07:49.453 に答える
0

(わかりました、誰も熱心に見えないので、私は洗練されていないことをして、自分の質問への回答を投稿します).

意図しない循環リンクを壊そうとかなりの調査を行った結果、このldオプション--exclude-libsが慰めになることを発見しました。基本的に、DLL の作成libmfx.a中にシンボルを使用して依存関係を解決した後、シンボルを強制的に削除する方法を探していました。これは、次のようlib.oに作成することで実現できます。so

g++ -shared -o lib-a.so lib.o -L/opt/intel/mediasdk/lib/lin_x64 -lmfx -Wl,--exclude-libs=libmfx

ライブラリがこのように作成されると、ボブの叔父さんは次のようになります。

g++ -o main-so-a main.o lib-a.so -ldl

libdl( Intel の MFX (現在は の内部lib-a.so) がまだdlopenを検出するために使用しているため、 はまだ必要であることに注意してくださいlibmfxhw64.so)

ldマニュアルページから:

   --exclude-libs lib,lib,...
       Specifies a list of archive libraries from which symbols should not be
       automatically exported.  The library names may be delimited by commas or
       colons.  Specifying "--exclude-libs ALL" excludes symbols in all archive
       libraries from automatic export.  This option is available only for the
       i386 PE targeted port of the linker and for ELF targeted ports.  For i386
       PE, symbols explicitly listed in a .def file are still exported,
       regardless of this option.  For ELF targeted ports, symbols affected
       by this option will be treated as hidden.

したがって、本質的には、関連する ELF シンボルがhiddenとマークされていることを確認することはできません。通常、これは#pragmaライブラリ開発者 (Intel など) によって s を介して処理されますが、彼らの過失により、この場合は後付けする必要があります。

マップ ファイルでも同じことができたと思いますが、とにかく--version-script完全にカプセル化する必要があるため、それはより脆弱であることが判明した可能性があります。libmfx.a

于 2015-07-21T07:59:29.600 に答える