Building a program with -D_LIBCPP_DEBUG=1 against a libc++ that is not itself built with that define

At least with recent LLVM 14 trunk,

$ cat test.cc
#include <string>
int main() { "longlonglonglonglonglong" + std::to_string(0); }

$ clang++ -stdlib=libc++ -D_LIBCPP_DEBUG=1 test.cc
$ ./a.out
Segmentation fault

at

#0 std::__1::__libcpp_db::swap (this=0x7f3187f63318 <std::__1::__get_db()::db>, c1=<optimized out>, c2=0x7ffe55d37840) at src/debug.cpp:461
#1 0x0000000000401744 in std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string (this=0x7ffe55d37858, __str=...) at include/c++/v1/string:1991
#2 0x0000000000401334 in std::__1::operator+<char, std::__1::char_traits<char>, std::__1::allocator<char> > (__lhs=0x403010 "longlonglonglonglonglong", __rhs=...) at include/c++/v1/string:4342
#3 0x00000000004012a9 in main () at test.cc:2

because the std::string instance returned from std::to_string (implemented in libc++, not itself built with -D_LIBCPP_DEBUG=1) never called __libcpp_db::__insert_c(this), so __libcpp_db::swap doesn't find it in the __cbeg_/__cend_ table and then dereferences a null pointer.

I wonder how usable and mature -D_LIBCPP_DEBUG=1 is considered in practice. Is this a well-known shortcoming (in which case it might be good to mention it explicitly in libcxx/docs/DesignDocs/DebugMode.rst, beyond just "Users should compile their whole program at the same debugging level."), or would it be worth filing a bug?

Just to link up the two threads: I ran into this earlier this year.
https://lists.llvm.org/pipermail/libcxx-dev/2021-May/001119.html

It is the reason at least one test in libcxx/test/ is marked “LIBCXX-DEBUG-FIXME”. I don’t have any ideas how to fix it, though.

–Arthur

At least with recent LLVM 14 trunk,
[…]

Segmentation fault
[…]
because the std::string instance returned from std::to_string
(implemented in libc++, not itself built with -D_LIBCPP_DEBUG=1) never
called __libcpp_db::__insert_c(this), so __libcpp_db::swap doesn’t find
it in the _cbeg/_cend table and then dereferences a null pointer.

I wonder how usable and mature -D_LIBCPP_DEBUG=1 is considered in
practice. Is this a well-known shortcoming (in which case it might be
good to mention it explicitly in libcxx/docs/DesignDocs/DebugMode.rst,
beyond just “Users should compile their whole program at the same
debugging level.”), or would it be worth filing a bug?

On the maturity level: libc++'s debugging mode is quite broken at the moment, however it is on my high priority list of things to fix.
That being said, even after it is fixed, you will not be able to just #define _LIBCPP_DEBUG 1 in your own translation unit.
You will need to use a libc++ that has been built for the debug mode in order for things to work.

However, once I’m done fixing the mess, you should be able to use something akin to #define _LIBCPP_ENABLE_ASSERTIONS
to get most non-ABI-or-performance-altering assertions enabled in just your TU. Things such as assertions if you index a
vector beyond its bounds.

Cheers,
Louis

That sounds like a good plan. Something like _LIBCPP_ENABLE_ASSERTIONS
would potentially be very interesting for Chromium.

Thanks,
Hans