Hi
Here is the integration of libbacktrace to provide the backtrace
on _GLIBCXX_DEBUG assertions.
I decided to integrate it without impacting the build scripts.
Users just need to install libbacktrace and once done _GLIBCXX_DEBUG
will look for it and start using it if supported. The drawback is that
as soon as libbacktrace is installed users will have to add
-lbacktrace in order to use _GLIBCXX_DEBUG mode. But I expect that if
you install libbacktrace it is for a reason.
Note that when libbacktrace is not supported I include stdint.h to
get uintptr_t, I hope it is the correct way to get it in a portable
way.
I also explcitely define BACKTRACE_SUPPORTED to 0 to make sure
libstdc++ has no libbacktrace dependency after usual build.
As it starts to make a lot of information displayed on Debug
assertion I have created print_function to filter output of functions.
It removes things like __cxx1998::, std::allocator and greatly
simplified _Safe_iterator rendering.
Here is an example of output when building
23_containers/vector/debug/construct3_neg.cc:
/home/fdt/dev/gcc/install/include/c++/9.0.0/debug/safe_iterator.h:321:
In function:
__gnu_debug::_Safe_iterator<_Iterator, _Sequence, _Category>&
__gnu_debug::_Safe_iterator<_Iterator, _Sequence,
_Category>::operator++() [with _Iterator = std::_List_iterator<int>;
_Sequence = std::__debug::list<int>; _Category =
std::forward_iterator_tag]
Backtrace:
0x40275f
__gnu_debug::_Safe_iterator<std::_List_iterator<int>>::operator++()
/home/fdt/dev/gcc/install/include/c++/9.0.0/debug/safe_iterator.h:321
0x402181
__gnu_debug::_Safe_iterator<std::_List_iterator<int>>::operator++()
/home/fdt/dev/gcc/install/include/c++/9.0.0/debug/safe_iterator.h:570
0x404082 std::iterator_traits<__gnu_debug::_Safe_iterator<std::_List_iterator<int>>
::difference_type
std::__distance<__gnu_debug::_Safe_iterator<std::_List_iterator<int>>
(__gnu_debug::_Safe_iterator<std::_List_iterator<int>>,
__gnu_debug::_Safe_iterator<std::_List_iterator<int>>,
std::input_iterator_tag)
/home/fdt/dev/gcc/install/include/c++/9.0.0/bits/stl_iterator_base_funcs.h:89
0x403795 std::iterator_traits<__gnu_debug::_Safe_iterator<std::_List_iterator<int>>
::difference_type
std::distance<__gnu_debug::_Safe_iterator<std::_List_iterator<int>>
(__gnu_debug::_Safe_iterator<std::_List_iterator<int>>,
__gnu_debug::_Safe_iterator<std::_List_iterator<int>>)
/home/fdt/dev/gcc/install/include/c++/9.0.0/bits/stl_iterator_base_funcs.h:141
0x4030b9 void std::vector<int>::_M_range_initialize<__gnu_debug::_Safe_iterator<std::_List_iterator<int>>
(__gnu_debug::_Safe_iterator<std::_List_iterator<int>>,
__gnu_debug::_Safe_iterator<std::_List_iterator<int>>,
std::forward_iterator_tag)
/home/fdt/dev/gcc/install/include/c++/9.0.0/bits/stl_vector.h:1541
0x402a2d std::vector<int>::vector<__gnu_debug::_Safe_iterator<std::_List_iterator<int>>,
void>(__gnu_debug::_Safe_iterator<std::_List_iterator<int>>,
__gnu_debug::_Safe_iterator<std::_List_iterator<int>>)
/home/fdt/dev/gcc/install/include/c++/9.0.0/bits/stl_vector.h:618
0x4022ec std::__debug::vector<int>::vector<__gnu_debug::_Safe_iterator<std::_List_iterator<int>>,
void>(__gnu_debug::_Safe_iterator<std::_List_iterator<int>>,
__gnu_debug::_Safe_iterator<std::_List_iterator<int>>)
/home/fdt/dev/gcc/install/include/c++/9.0.0/debug/vector:195
0x401e2c void
__gnu_test::check_construct3<std::__debug::vector<int> >()
./util/debug/checks.h:234
0x401460 test01()
/home/fdt/dev/poc/construct3_neg.cc:26
0x40146c main
/home/fdt/dev/poc/construct3_neg.cc:31
Error: attempt to increment a past-the-end iterator.
Objects involved in the operation:
iterator "this" @ 0x0x7fff068adce0 {
type = std::_List_iterator<int> (mutable iterator);
state = past-the-end;
references sequence with type 'std::__debug::list<int>' @
0x0x7fff068ae080
}
* include/debug/formatter.h: Check for backtrace-supported.h access
and include it.
[BACKTRACE_SUPPORTED] Include <backtrace.h>
(_Error_formatter::_Bt_full_t): New function pointer type.
(_Error_formatter::_M_backtrace_state): New.
(_Error_formatter::_M_backtrace_full_func): New.
* src/c++11/debug.cc: Include <cstring>.
(PrintContext::_M_demangle_name): New.
(_Print_func_t): New.
(print_word(PrintContext&, const char*)): New.
(print_raw(PrintContext&, const char*)): New.
(print_function(PrintContext&, const char*, _Print_func_t)): New.
(print_type): Use latter.
(print_string(PrintContext&, const char*)): New.
(print_backtrace(void*, uintptr_t, const char*, int, const char*)):
New.
(_Error_formatter::_M_error()): Adapt.
Tested under Linux x86_64.
Ok to commit ? One day ?