Leonard Chan via llvm-dev
2021-Sep-02 00:16 UTC
[llvm-dev] Issue with libc++abi Demangling for Sanitizers
Hi all, I ran into an issue where it looks like the libc++abi demangler isn't being used at all by sanitizer runtimes despite libc++abi being statically linked against. That is, if I were to make an executable that statically linked against libc++abi.a (which has a strong definition for `__cxa_demangle`) and libclang_rt.tsan.a (which has a weak reference to `__cxa_demangle`), then my final executable will contain an undefined weak `__cxa_demangle` symbol. This happens because the tsan runtime has no strong reference to `__cxa_demangle`, and thus will not link in libc++abi.a(cxx_demangle.cpp.o), the object file containing the actual definition for __cxa_demangle. I hit this while running compiler-rt tests and found that some tests which require libc++abi (and actually link against libc++abi.a) do not actually symbolize correctly and thus fail. We could work around this in tests by adding `-u __cxa_demangle` to compiler-rt tests, but that seems like an undesirable workaround that's only limited to tests, and would differ from how users actually use sanitizers (unless it was added to the driver given some sanitizer flags, but I'm not sure if we'd want that). My question is: *what are ways libc++abi can correctly be statically linked in with sanitizer runtimes (that is, get __cxa_demangle to properly manifest)? *I'm assuming that it was intentional for (1) __cxa_demangle to be weakly referenced because sanitizers should still be able to work without libc++abi, and (2) libc++abi.a is meant to be statically linked in with sanitizer runtimes so, if it was used, then it would only link parts of libc++abi and not the bulk of it. Thanks, Leonard -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210901/f0732d4c/attachment.html>
Fangrui Song via llvm-dev
2021-Sep-05 19:02 UTC
[llvm-dev] Issue with libc++abi Demangling for Sanitizers
On 2021-09-01, Leonard Chan via llvm-dev wrote:>Hi all, > >I ran into an issue where it looks like the libc++abi demangler isn't being >used at all by sanitizer runtimes despite libc++abi being statically linked >against. That is, if I were to make an executable that statically linked >against libc++abi.a (which has a strong definition for `__cxa_demangle`) >and libclang_rt.tsan.a (which has a weak reference to `__cxa_demangle`), >then my final executable will contain an undefined weak `__cxa_demangle` >symbol. This happens because the tsan runtime has no strong reference to >`__cxa_demangle`, and thus will not link in >libc++abi.a(cxx_demangle.cpp.o), the object file containing the actual >definition for __cxa_demangle. > >I hit this while running compiler-rt tests and found that some tests which >require libc++abi (and actually link against libc++abi.a) do not actually >symbolize correctly and thus fail. We could work around this in tests by >adding `-u __cxa_demangle` to compiler-rt tests, but that seems like an >undesirable workaround that's only limited to tests, and would differ from >how users actually use sanitizers (unless it was added to the driver given >some sanitizer flags, but I'm not sure if we'd want that). > >My question is: *what are ways libc++abi can correctly be statically linked >in with sanitizer runtimes (that is, get __cxa_demangle to properly >manifest)? *I'm assuming that it was intentional for (1) __cxa_demangle to >be weakly referenced because sanitizers should still be able to work >without libc++abi, and (2) libc++abi.a is meant to be statically linked in >with sanitizer runtimes so, if it was used, then it would only link parts >of libc++abi and not the bulk of it. > >Thanks, >LeonardThere is no shortcut. The ELF specifications says "The link editor does not extract archive members to resolve undefined weak symbols." So the `__cxa_demangle` reference from compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp does not extract libc++abi.a. This works as intended. (Note: Mach-O ld64 happily extracts an archive to satisfy an undefined reference.) If you want to extract libc++abi.a(cxa_demangle.cpp.o), express the intention explicitly by using a non-weak reference, which can be any of: * non-weak reference of __cxa_demangle * -u __cxa_demangle * #pragma comment(lib, "c++abi")