Подтвердить что ты не робот

Есть ли недостаток в использовании -символических функций?

Недавно я обнаружил вариант компоновщика "-Bsymbolic-functions" в GNU ld:

-Bsymbolic
  When creating a shared library, bind references to global symbols to the 
  definition within the shared library, if any. Normally, it is possible 
  for a program linked against a shared library to override the definition 
  within the shared library. 

  This option is only meaningful on ELF platforms which support shared libraries.

-Bsymbolic-functions
  When creating a shared library, bind references to global function symbols 
  to the definition within the shared library, if any.  

  This option is only meaningful on ELF platforms which support shared libraries.

Это, по-видимому, является инверсией опции GCC -fvisibility=hidden, поскольку вместо предотвращения экспорта ссылочной функции другим общедоступным объектам она препятствует привязке внутренних библиотек библиотеки к этой функции к экспортируемой функции другого общего объекта. Я сообщил себе, что -Bsymbolic-functions будет препятствовать созданию PLT-записей для функций, что является хорошим побочным эффектом.

  • Но мне было интересно, есть ли более мелкомасштабный контроль над этим, например перезаписывание -Bsymbolic для отдельных определений функций библиотеки.

  • Должен ли я быть в курсе любых ошибок при использовании -Bsymbolic-functions? Я планирую использовать это, потому что -Bsymbolic будет прерывать исключения, я думаю (это сделает так, что ссылки на объекты типаinfo не объединены, я думаю).

Спасибо!

4b9b3361

Ответ 1

Отвечая на мой собственный вопрос, потому что я только что заработал значок Tumbleweed... и я узнал впоследствии

Но мне было интересно, есть ли более мелкомасштабный контроль над этим, например, перезаписывать -Bsymbolic для отдельных определений функций библиотеки.

Да, есть опция --dynamic-list, которая делает именно это

Должен ли я быть в курсе любых ошибок при использовании -Bsymbolic-functions? Я планирую использовать это, потому что -Bsymbolic нарушит исключения, я думаю (это сделает так, что ссылки на объекты типаinfo не объединены, я думаю).

Я больше посмотрел на него, и, похоже, проблем нет. Библиотека libstdС++, по-видимому, делает это или, по крайней мере, рассматривала ее, и им нужно было добавить --dynamic-list-cpp-new, чтобы по-прежнему иметь operator new unified (чтобы предотвратить смешивание нескольких распределителей/деллалокаторов в программе, но я бы сказал, что такие программы не работают так или иначе). Ubuntu использует его или использует его по умолчанию, и, похоже, он вызывает конфликты с некоторыми пакетами. Но в целом он должен хорошо работать, я ожидаю.

Ответ 2

Есть случаи с побочными эффектами. Документированный: https://bugs.launchpad.net/ubuntu/+source/xfe/+bug/644645 Я также хотел бы узнать больше об этом, потому что сейчас у меня такой случай.

Ответ 3

Создание glibc с -Бимволическими функциями не рекомендуется. Вот результат, который я получил:

Core was generated by `/home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/elf/ld-linux                                                               .'.
Program terminated with signal 11, Segmentation fault.
#0  0x400a3e90 in _int_free ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
(gdb) where
#0  0x400a3e90 in _int_free ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#1  0x4016b94b in __libc_dlsym ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#2  0x4004c2c7 in __gconv_find_shlib ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#3  0x40042320 in find_derivation ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#4  0x40042889 in __gconv_find_transform ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#5  0x400d6f00 in __wcsmbs_load_conv ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#6  0x400c86f6 in mbrtowc ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#7  0x08048914 in ?? ()
#8  0x00000000 in ?? ()

Ответ 4

Ну, вы могли бы сказать, что это "усиленная" опция, поскольку она гарантирует, что ваши вызовы в библиотечных функциях обязательно окажутся там. Но одна проблема, которую я обнаружил, - это тестовые наборы проектов.

Например, тестовый пакет libvirt хотел бы вызвать только что созданный libvirt0.so, а также посмеяться над некоторыми вызовами, которые будут сделаны оттуда.

Из-за того, что -Bsymbolic-functions используются в сборке, что нарушает тест как исходный, а не проверяемая функция вызывается.

Пример обратной трассировки Хороший случай:

#0  virHostCPUGetThreadsPerSubcore (arch=VIR_ARCH_PPC64) at ../../../tests/virhostcpumock.c:30
#1  0x00007ffff7c1e4c4 in virHostCPUGetInfoPopulateLinux (cpuinfo=<optimized out>, arch=VIR_ARCH_PPC64, cpus=0x7fffffffdf38, mhz=<optimized out>, nodes=0x7fffffffdf40, sockets=0x7fffffffdf44, cores=0x7fffffffdf48, threads=0x7fffffffdf4c)
    at ../../../src/util/virhostcpu.c:661                                           
#2  0x0000555555557e6f in linuxTestCompareFiles (outputfile=0x55555558f150 "/build/libvirt-OUKR8i/libvirt-4.10.0/tests/virhostcpudata/linux-ppc64-subcores2.expected", arch=VIR_ARCH_PPC64,·
    cpuinfofile=0x5555555a3f10 "/build/libvirt-OUKR8i/libvirt-4.10.0/tests/virhostcpudata/linux-ppc64-subcores2.cpuinfo") at ../../../tests/virhostcputest.c:44
#3  linuxTestHostCPU (opaque=<optimized out>) at ../../../tests/virhostcputest.c:189
#4  0x000055555555914d in virTestRun (title=0x55555555c0a1 "subcores2", body=0x555555557cc0 <linuxTestHostCPU>, data=0x7fffffffe0c0) at ../../../tests/testutils.c:176
#5  0x000055555555781a in mymain () at ../../../tests/virhostcputest.c:263          
#6  0x0000555555559df4 in virTestMain (argc=1, argv=0x7fffffffe2c8, func=0x5555555577b0 <mymain>) at ../../../tests/testutils.c:1114
#7  0x00007ffff79bb09b in __libc_start_main (main=0x5555555576a0 <main>, argc=1, argv=0x7fffffffe2c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe2b8) at ../csu/libc-start.c:308
#8  0x00005555555576ea in _start () at ../../../tests/virhostcputest.c:278 

Плохой случай:

#0  virHostCPUGetThreadsPerSubcore ([email protected]=VIR_ARCH_PPC64) at ../../../src/util/virhostcpu.c:1119
#1  0x00007ffff7c27e04 in virHostCPUGetInfoPopulateLinux (cpuinfo=<optimized out>, arch=VIR_ARCH_PPC64, cpus=0x7fffffffdea8, mhz=<optimized out>, nodes=0x7fffffffdeb0, sockets=0x7fffffffdeb4, cores=0x7fffffffdeb8, threads=0x7fffffffdebc)
    at ../../../src/util/virhostcpu.c:661                                           
#2  0x0000555555557e6f in linuxTestCompareFiles (outputfile=0x5555555a5c30 "/build/libvirt-4biJ7f/libvirt-4.10.0/tests/virhostcpudata/linux-ppc64-subcores2.expected", arch=VIR_ARCH_PPC64,·
    cpuinfofile=0x55555558fd20 "/build/libvirt-4biJ7f/libvirt-4.10.0/tests/virhostcpudata/linux-ppc64-subcores2.cpuinfo") at ../../../tests/virhostcputest.c:44
#3  linuxTestHostCPU (opaque=<optimized out>) at ../../../tests/virhostcputest.c:189
#4  0x000055555555914d in virTestRun (title=0x55555555c0a1 "subcores2", body=0x555555557cc0 <linuxTestHostCPU>, data=0x7fffffffe030) at ../../../tests/testutils.c:176
#5  0x000055555555781a in mymain () at ../../../tests/virhostcputest.c:263          
#6  0x0000555555559df4 in virTestMain (argc=1, argv=0x7fffffffe238, func=0x5555555577b0 <mymain>) at ../../../tests/testutils.c:1114
#7  0x00007ffff79b009b in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#8  0x00005555555576ea in _start () at ../../../tests/virhostcputest.c:278 

Сравните источник этих данных для virHostCPUGetThreadsPerSubcore и вы увидите разницу.

Другой случай, который я видел:

Поскольку первоначальный вопрос касался потенциальных недостатков, я подумал, что стоит упомянуть и эту довольно распространенную категорию связанных вопросов.