François Dumont
2018-12-10 23:08:12 UTC
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>>
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>>
/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>>
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 ?
François
   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 ?
François