[llvm-dev] Issue with libc++abi Demangling for Sanitizers

Fangrui Song via llvm-dev llvm-dev at lists.llvm.org
Sun Sep 5 12:02:41 PDT 2021


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,
>Leonard

There 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")


More information about the llvm-dev mailing list