You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I encountered a crash on my project when trying to use libassert with sanitizers enabled:
==512519==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6240000480f0 at pc 0x798d9a919163 bp 0x7ffe12fa5700 sp 0x7ffe12fa56f8
READ of size 8 at 0x6240000480f0 thread T0
#0 0x798d9a919162 in dwarf_dealloc /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_alloc.c:925
#1 0x798d9a83f166 in cpptrace::detail::libdwarf::die_object::get_string_attribute[abi:cxx11](unsigned short) const::{lambda(char*)#1}::operator()(char*) const /home/user/project/build/_deps/cpptrace-src/src/symbols/dwarf/dwarf.hpp:152
#2 0x798d9a867bb9 in cpptrace::detail::raii_wrapper<char*, cpptrace::detail::libdwarf::die_object::get_string_attribute(unsigned short) const::{lambda(char*)#1}, 0, 0>::~raii_wrapper() /home/user/project/build/_deps/cpptrace-src/src/utils/utils.hpp:231
#3 0x798d9a83f7d4 in cpptrace::detail::libdwarf::die_object::get_string_attribute[abi:cxx11](unsigned short) const /home/user/project/build/_deps/cpptrace-src/src/symbols/dwarf/dwarf.hpp:155
#4 0x798d9a85022a in cpptrace::detail::libdwarf::dwarf_resolver::subprogram_symbol[abi:cxx11](cpptrace::detail::libdwarf::die_object const&, unsigned short) /home/user/project/build/_deps/cpptrace-src/src/symbols/dwarf/dwarf_resolver.cpp:287
#5 0x798d9a854bf0 in cpptrace::detail::libdwarf::dwarf_resolver::retrieve_symbol_for_subprogram[abi:cxx11](cpptrace::detail::libdwarf::die_object const&, cpptrace::detail::libdwarf::die_object const&, unsigned long long, unsigned short, std::vector<cpptrace::stacktrace_frame, std::allocator<cpptrace::stacktrace_frame> >&) /home/user/project/build/_deps/cpptrace-src/src/symbols/dwarf/dwarf_resolver.cpp:426
#6 0x798d9a858350 in cpptrace::detail::libdwarf::dwarf_resolver::retrieve_symbol(cpptrace::detail::libdwarf::die_object const&, unsigned long long, unsigned short, cpptrace::stacktrace_frame&, std::vector<cpptrace::stacktrace_frame, std::allocator<cpptrace::stacktrace_frame> >&) /home/user/project/build/_deps/cpptrace-src/src/symbols/dwarf/dwarf_resolver.cpp:576
#7 0x798d9a8641c5 in cpptrace::detail::libdwarf::dwarf_resolver::resolve_frame_core(cpptrace::object_frame const&, cpptrace::stacktrace_frame&, std::vector<cpptrace::stacktrace_frame, std::allocator<cpptrace::stacktrace_frame> >&) (/home/user/project/build/lib/libcpptrace.so.0+0x8641c5)
#8 0x798d9a864fdb in cpptrace::detail::libdwarf::dwarf_resolver::resolve_frame(cpptrace::object_frame const&) /home/user/project/build/_deps/cpptrace-src/src/symbols/dwarf/dwarf_resolver.cpp:1003
#9 0x798d9a900d53 in cpptrace::detail::libdwarf::resolve_frames(std::vector<cpptrace::object_frame, std::allocator<cpptrace::object_frame> > const&) /home/user/project/build/_deps/cpptrace-src/src/symbols/symbols_with_libdwarf.cpp:108
#10 0x798d9a8e8fb5 in cpptrace::detail::resolve_frames(std::vector<unsigned long, std::allocator<unsigned long> > const&) /home/user/project/build/_deps/cpptrace-src/src/symbols/symbols_core.cpp:138
#11 0x798d9a7e3cbb in cpptrace::raw_trace::resolve() const /home/user/project/build/_deps/cpptrace-src/src/cpptrace.cpp:63
#12 0x798db6a547d6 in libassert::assertion_info::get_stacktrace() const /home/user/project/build/_deps/libassert-src/src/assert.cpp:593
#13 0x798db6a53437 in libassert::assertion_info::get_path_handler() const /home/user/project/build/_deps/libassert-src/src/assert.cpp:559
#14 0x798db6a561ca in libassert::assertion_info::tagline[abi:cxx11](libassert::color_scheme const&) const /home/user/project/build/_deps/libassert-src/src/assert.cpp:620
#15 0x798db6a581fc in libassert::assertion_info::to_string[abi:cxx11](int, libassert::color_scheme const&) const /home/user/project/build/_deps/libassert-src/src/assert.cpp:672
#16 0x798db6a4bc60 in libassert::default_failure_handler(libassert::assertion_info const&) /home/user/project/build/_deps/libassert-src/src/assert.cpp:440
#17 0x798db6a4c044 in libassert::detail::fail(libassert::assertion_info const&) /home/user/project/build/_deps/libassert-src/src/assert.cpp:477
#18 0x1571b0f in void libassert::detail::process_assert_fail<int const&, int const&, libassert::detail::ops::eq, libassert::detail::pretty_function_name_wrapper>(libassert::detail::expression_decomposer<int const&, int const&, libassert::detail::ops::eq>&, libassert::detail::assert_static_parameters const*, libassert::detail::pretty_function_name_wrapper&&) /home/user/project/build/_deps/libassert-src/include/libassert/assert.hpp:455
#19 0x156d741 in void libassert::detail::process_assert_fail_n<int const&, int const&, libassert::detail::ops::eq, libassert::detail::pretty_function_name_wrapper>(libassert::detail::expression_decomposer<int const&, int const&, libassert::detail::ops::eq>, libassert::detail::assert_static_parameters const*, libassert::detail::pretty_function_name_wrapper&&) /home/user/project/build/_deps/libassert-src/include/libassert/assert.hpp:499
<...> SOME CALLS LEFT OUT
#26 0xc55fe1 in main /home/user/project/tester/tester.cc:192
#27 0x798d9923314d in __libc_start_call_main (/nix/store/3dyw8dzj9ab4m8hv5dpyx7zii8d0w6fi-glibc-2.39-52/lib/libc.so.6+0x2a14d) (BuildId: 2f905760df53ce9c82feec29b6013b6a72c58c95)
#28 0x798d99233208 in __libc_start_main_alias_1 (/nix/store/3dyw8dzj9ab4m8hv5dpyx7zii8d0w6fi-glibc-2.39-52/lib/libc.so.6+0x2a208) (BuildId: 2f905760df53ce9c82feec29b6013b6a72c58c95)
#29 0x75e1d4 in _start (/home/user/project/build/bin/mybin+0x75e1d4)
0x6240000480f0 is located 16 bytes before 7122-byte region [0x624000048100,0x624000049cd2)
allocated by thread T0 here:
#0 0x798dcbadc04f in __interceptor_malloc (/nix/store/wd68m1hnxwz2b3kazip9m9kmjg0my6gd-gcc-13.3.0-lib/lib/libasan.so.8+0xdc04f)
#1 0x798d9aad3423 in elf_load_nolibelf_section /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_elfread.c:230
#2 0x798d9a9c3503 in _dwarf_load_section /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_init_finish.c:1442
#3 0x798d9a96c9ce in _dwarf_extract_local_debug_str_string_given_offset /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_form.c:1978
#4 0x798d9a96e6fb in dwarf_formstring /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_form.c:2167
#5 0x798d9aa75b29 in dwarf_die_text /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_query.c:854
#6 0x798d9a928a8b in set_producer_type /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_die_deliv.c:1283
#7 0x798d9a929694 in find_cu_die_base_fields /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_die_deliv.c:1375
#8 0x798d9a924ed8 in finish_cu_context_via_cudie_inner /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_die_deliv.c:696
#9 0x798d9a92c21d in finish_up_cu_context_from_cudie /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_die_deliv.c:1734
#10 0x798d9a92d2aa in _dwarf_create_a_new_cu_context_record_on_list /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_die_deliv.c:1878
#11 0x798d9a938886 in dwarf_offdie_b /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_die_deliv.c:3296
#12 0x798d9a87f2b2 in int cpptrace::detail::libdwarf::dwarf_resolver::wrap<Dwarf_Debug_s*, unsigned long long, int, Dwarf_Die_s**, Dwarf_Error_s**, cpptrace::detail::raii_wrapper<Dwarf_Debug_s*, void (*)(Dwarf_Debug_s*), 0, 0>&, unsigned long long&, bool, Dwarf_Die_s**, 0>(int (*)(Dwarf_Debug_s*, unsigned long long, int, Dwarf_Die_s**, Dwarf_Error_s**), cpptrace::detail::raii_wrapper<Dwarf_Debug_s*, void (*)(Dwarf_Debug_s*), 0, 0>&, unsigned long long&, bool&&, Dwarf_Die_s**&&) const /home/user/project/build/_deps/cpptrace-src/src/symbols/dwarf/dwarf_resolver.cpp:97
#13 0x798d9a85fe7c in cpptrace::detail::libdwarf::dwarf_resolver::lookup_cu(unsigned long long) /home/user/project/build/_deps/cpptrace-src/src/symbols/dwarf/dwarf_resolver.cpp:802
#14 0x798d9a863b5c in cpptrace::detail::libdwarf::dwarf_resolver::resolve_frame_core(cpptrace::object_frame const&, cpptrace::stacktrace_frame&, std::vector<cpptrace::stacktrace_frame, std::allocator<cpptrace::stacktrace_frame> >&) (/home/user/project/build/lib/libcpptrace.so.0+0x863b5c)
#15 0x798d9a864fdb in cpptrace::detail::libdwarf::dwarf_resolver::resolve_frame(cpptrace::object_frame const&) /home/user/project/build/_deps/cpptrace-src/src/symbols/dwarf/dwarf_resolver.cpp:1003
#16 0x798d9a900d53 in cpptrace::detail::libdwarf::resolve_frames(std::vector<cpptrace::object_frame, std::allocator<cpptrace::object_frame> > const&) /home/user/project/build/_deps/cpptrace-src/src/symbols/symbols_with_libdwarf.cpp:108
#17 0x798d9a8e8fb5 in cpptrace::detail::resolve_frames(std::vector<unsigned long, std::allocator<unsigned long> > const&) /home/user/project/build/_deps/cpptrace-src/src/symbols/symbols_core.cpp:138
#18 0x798d9a7e3cbb in cpptrace::raw_trace::resolve() const /home/user/project/build/_deps/cpptrace-src/src/cpptrace.cpp:63
#19 0x798db6a547d6 in libassert::assertion_info::get_stacktrace() const /home/user/project/build/_deps/libassert-src/src/assert.cpp:593
#20 0x798db6a53437 in libassert::assertion_info::get_path_handler() const /home/user/project/build/_deps/libassert-src/src/assert.cpp:559
#21 0x798db6a561ca in libassert::assertion_info::tagline[abi:cxx11](libassert::color_scheme const&) const /home/user/project/build/_deps/libassert-src/src/assert.cpp:620
#22 0x798db6a581fc in libassert::assertion_info::to_string[abi:cxx11](int, libassert::color_scheme const&) const /home/user/project/build/_deps/libassert-src/src/assert.cpp:672
#23 0x798db6a4bc60 in libassert::default_failure_handler(libassert::assertion_info const&) /home/user/project/build/_deps/libassert-src/src/assert.cpp:440
#24 0x798db6a4c044 in libassert::detail::fail(libassert::assertion_info const&) /home/user/project/build/_deps/libassert-src/src/assert.cpp:477
#25 0x1571b0f in void libassert::detail::process_assert_fail<int const&, int const&, libassert::detail::ops::eq, libassert::detail::pretty_function_name_wrapper>(libassert::detail::expression_decomposer<int const&, int const&, libassert::detail::ops::eq>&, libassert::detail::assert_static_parameters const*, libassert::detail::pretty_function_name_wrapper&&) /home/user/project/build/_deps/libassert-src/include/libassert/assert.hpp:455
#26 0x156d741 in void libassert::detail::process_assert_fail_n<int const&, int const&, libassert::detail::ops::eq, libassert::detail::pretty_function_name_wrapper>(libassert::detail::expression_decomposer<int const&, int const&, libassert::detail::ops::eq>, libassert::detail::assert_static_parameters const*, libassert::detail::pretty_function_name_wrapper&&) /home/user/project/build/_deps/libassert-src/include/libassert/assert.hpp:499
<...> SOME CALLS LEFT OUT
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/user/project/build/_deps/libdwarf-src/src/lib/libdwarf/dwarf_alloc.c:925 in dwarf_dealloc
Shadow bytes around the buggy address:
0x624000047e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x624000047e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x624000047f00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x624000047f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x624000048000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x624000048080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[fa]fa
0x624000048100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x624000048180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x624000048200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x624000048280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x624000048300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==512519==ABORTING
It looks like it was caused by my (mis)usage of add_compile_options and add_link_options in my CmakeLists.txt to add -fsanitize= which probably leaked the flags to libdwarf.
I was not able to reproduce with a smaller project. All I got were link errors about various symbols from ASan not being found by libdwarf. This led me to solve the issue by replacing add_{compile,link}_options with target_{compile,link}_options.
Leaking the sanitizer flags to libdwarf is ok, it is often helpful to compile an entire project (including libraries) with sanitizers. I'm glad you're able to work around this so you could unblock.
In general any sanitizer issue is a bug (false positives are pretty rare) so I am definitely interested in tracking this issue down.
Looking into this, the error is really odd. cpptrace::detail::libdwarf::die_object::get_string_attribute is a heavily used codepath and I've never seen any problems before, cpptrace should be freeing things properly. The traces make it looks like dwarf_dealloc is trying to access data in the loaded debug information which doesn't make much sense to me. If the string isn't allocated it shouldn't be deallocated but it appears it is definitely correct to dwarf_dealloc the string from dwarf_formstring, so I'm a bit confused. I've opened an issue upstream to ask about this.
It would be really helpful to get some additional information here about what compiler you're using and how you're compiling. Ideally I'd like to be able to reproduce this but that can sometimes be hard. If you are able to send the compiled program where this was failing that could be helpful for diagnosing what's going on with libdwarf and cpptrace here.
Hi and thanks for this awesome lib!
I encountered a crash on my project when trying to use libassert with sanitizers enabled:
It looks like it was caused by my (mis)usage of
add_compile_options
andadd_link_options
in myCmakeLists.txt
to add-fsanitize=
which probably leaked the flags to libdwarf.I was not able to reproduce with a smaller project. All I got were link errors about various symbols from ASan not being found by libdwarf. This led me to solve the issue by replacing
add_{compile,link}_options
withtarget_{compile,link}_options
.It's not really an issue of libaddress, but is/was a blocker to using it, so I'm putting it here in case it helps someone else 🤷
The text was updated successfully, but these errors were encountered: