Is there a downside to using -Bsymbolic-functions?

前端 未结 4 729
被撕碎了的回忆
被撕碎了的回忆 2020-12-24 12:54

I recently discovered the linker option \"-Bsymbolic-functions\" in GNU ld:

-Bsymbolic
  When creating a shared library, bind references to global symbols to         


        
相关标签:
4条回答
  • 2020-12-24 13:29

    Answering my own question because I just earned a Tumbleweed badge for it... and I found out subsequently

    But I was wondering whether there is perhaps a finer-grained control over this, like overwriting -Bsymbolic for individual function definitions of a library.

    Yes, there is the option --dynamic-list which does exactly that

    Should I be aware of any pitfalls of using -Bsymbolic-functions? I plan to only use that, because the -Bsymbolic will break exceptions, I think (it will make it so that references to typeinfo objects are not unified, I think).

    I looked more into it, and it seems there is no issue. The libstdc++ library apparently does it or at least did consider it and they only had to add --dynamic-list-cpp-new to still have operator new unified (to prevent issues with multiple allocator / deallocators mixing up in a program but I would argue such programs are broken anyway). Ubuntu uses it or used it by default, and it seems it causes conflicts with some packages. But overall it should work nicely I expect.

    0 讨论(0)
  • 2020-12-24 13:32

    There are cases with side effects. A documented one: https://bugs.launchpad.net/ubuntu/+source/xfe/+bug/644645 I would also like to figure out more about it, because I have such a case right now.

    0 讨论(0)
  • 2020-12-24 13:33

    Well you could say it is a "hardening" option as it ensures your calls to in-library functions surely end up there. But one issue that I found is some projects test-suites.

    For example the libvirt test-suite would want to call into the just built libvirt0.so but also mock some of the calls that will be done from there.

    Due to -Bsymbolic-functions being used on the build that breaks the test as the original and not the mocked function is called.

    Example backtraces Good case:

    #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 
    

    Bad case:

    #0  virHostCPUGetThreadsPerSubcore (arch=arch@entry=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 
    

    Compare the source for virHostCPUGetThreadsPerSubcore in those two and you will see the difference.

    Another case I have seen are:

    • static variables becoming multiple instances in singularity
    • segfaulting tests in sssd
    • autofs issues with global variables

    Since the original question was about potential drawbacks I thought it is worth to mention those somewhat common category of related issues as well.

    0 讨论(0)
  • 2020-12-24 13:35

    building glibc with -Bsymbolic-functions is not recommended neither. Here is the result I got:

    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 ?? ()
    
    0 讨论(0)
提交回复
热议问题