This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: libbacktrace integration for _GLIBCXX_DEBUG mode


On 11/12/18 00:08 +0100, François Dumont wrote:
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 ?

Maybe one day, but not now during stage 3.

I'm concerned about the requirement to link to libbacktrace
explicitly (which will break existing makefiles and build systems that
currently use debug mode in testing).

Also, some of the glibc team pointed out to me that running *any*
extra code after undefined behaviour has been detected is a potential
risk. The less that you do between detecting UB and calling abort(),
the better. Giving the users more information is helpful, but comes
with some additional risk.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]