Discussion:
libbacktrace integration for _GLIBCXX_DEBUG mode
François Dumont
2018-12-10 23:08:12 UTC
Permalink
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 ?

François

Loading...