2015-04-28 8 views
1

(В то время как форум Intel является более естественным местом, чтобы спросить this question я отправляю его здесь в надежде на большую активность, чем полное отсутствие Intel, их - до сих пор)MFXInit() в libmfx.a ошибке сегментации при вызове из общего объекта

Я не могу создать динамическую библиотеку ссылок, которая использует Intel Media SDK (linux server) для управления видео h264 и заметила проблему в дизайне библиотеки MFX. Как я понимаю, программа предполагается связать с статической библиотеки, как:

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

Однако эта 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.a - dlopen()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() на StackFrame #3 является тот, в libmfx.a в то время как один в #1 в libmfxhw64.so.)

Обратите внимание, что не существует нет сбой при mylib создается как статические библиотеки. Использование контрольных точек и дизассемблер, мне удалось сделать следующий трассировку снимок, где в обоих случаях #1 является на MFXInit+424, но они появляются ударить различные версии MFXQueryVersion (абсолютные адреса не имеют смысла в связи с переездом):

#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 кишок непосредственно, но я полагаю, что в обходе статический «диспетчер» без гарантии (?)

может кто-то объяснить, Intel, идея позади дизайна? Spec., Зачем предоставлять статическую библиотеку, которая делегирует только .so, имеющую идентичный интерфейс?

Также представляется, что SEGV вызван статическими/глобальными данными в libmfx.a или libmfxhw64.so. Есть ли способ принудительно выполнить конкретный порядок выполнения динамически загруженных статических/глобальных разделов? Каков наилучший подход для отладки этих проблем?


Испытано с Intel Media SDK R2 (Ubuntu 12) и Intel Media SDK 2015R3-R5 (Centos 7, 1,13/1,15) на Intel Haswell i7-4790 @ 3.6GHz

Если у вас есть рабочий Intel MSDK setup, пожалуйста, скомпилируйте my example code, чтобы подтвердить эту проблему.

ответ

0

(Хорошо, поскольку никто не выглядит нетерпеливым, я сделаю неэлегантную вещь и опубликую ответ на свой вопрос).

После значительных исследований, пытающихся сломать непреднамеренное круговое соединение, я обнаружил, что опция ld--exclude-libs обеспечивает утешение. По сути, я искал способ принудительно удалить любые символы libmfx.a после их использования для разрешения зависимостей в lib.o при создании DLL. Это может быть достигнуто путем создания 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 отмечены скрыто. Обычно это обрабатывается разработчиками библиотеки (т.е. Intel) через #pragma s, но из-за их небрежности в этом случае необходимо дооснастить.

Я полагаю, что то же самое можно было бы сделать с картографическим файлом --version-script, но это, возможно, оказалось более хрупким, так как мы хотим полностью инкапсулировать libmfx.a в любом случае.

3

В самом конце файла «ридй-диспетчерский-linux.pdf» в последних версии исходного кода диспетчерской, там это:

Существует небольшая разница между использованием диспетчером библиотеки из исполняемых модуля или общего объекта. Для того, чтобы смягчить символ конфликта между собой и SDK разделяемым объектом на Linux *, приложение должно: 1) ссылка на libdispatch_shared.a вместо libmfx.a 2) определяют MFX_DISPATCHER_EXPOSED_PREFIX перед любой SDK включает в себя

Я использовал этот , и он работает для решения проблемы конфликта символов, которую вы описываете.

Вы можете найти этот файл, если вы установите «Intel Media Server Studio Professional 2016». Существует бесплатная версия сообщества.Исходные файлы и PDF-файлы будут найдены в/opt/intel/mediasdk/opensource/