bombela / backward-cpp

A beautiful stack trace pretty printer for C++
MIT License
3.66k stars 465 forks source link

MemorySanitizer: use-of-uninitialized-value in combination with bfd #243

Open greenrobot opened 2 years ago

greenrobot commented 2 years ago

Got this with clang 13 and msan with a release build:

==47098==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x781634 in backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::find_in_section(unsigned long, unsigned long, backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::bfd_fileobject*, bfd_section*, backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::find_sym_result&) /home/jenkins/agent/workspace/ObjectBox-Sanitizers_cluster/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:1679:9
    #1 0x1721cfb in bfd_map_over_sections (/home/jenkins/agent/workspace/ObjectBox-Sanitizers_cluster/cbuild/Release-msan/objectbox/src/main/cpp/objectbox-test+0x1721cfb)
    #2 0x775db7 in backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::find_symbol_details(backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::bfd_fileobject*, void*, void*) /home/jenkins/agent/workspace/ObjectBox-Sanitizers_cluster/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:1660:5
    #3 0x775db7 in backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::resolve(backward::ResolvedTrace) /home/jenkins/agent/workspace/ObjectBox-Sanitizers_cluster/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:1443:9
    #4 0x78371b in void backward::Printer::print_stacktrace<backward::StackTrace>(backward::StackTrace&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&, backward::Colorize&) /home/jenkins/agent/workspace/ObjectBox-Sanitizers_cluster/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:4034:33
    #5 0x772c06 in std::__1::basic_ostream<char, std::__1::char_traits<char> >& backward::Printer::print<backward::StackTrace>(backward::StackTrace&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&) /home/jenkins/agent/workspace/ObjectBox-Sanitizers_cluster/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:4000:5
greenrobot commented 2 years ago

Another one (clang 12.0.1, but should not make a difference; got the one above also with 12.0.1).

Note I added some printf etc around lines 1675 - 1686, so line numbers moved back by around 4 after that.

==416891==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x78867c in backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::resolve(backward::ResolvedTrace) /home/markus/dev/objectbox/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:1474:11
    #1 0x794bd6 in void backward::Printer::print_stacktrace<backward::StackTrace const>(backward::StackTrace const&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&, backward::Colorize&) /home/markus/dev/objectbox/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:4040:33
    #2 0x78420d in std::__1::basic_ostream<char, std::__1::char_traits<char> >& backward::Printer::print<backward::StackTrace const>(backward::StackTrace const&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&) /home/markus/dev/objectbox/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:4006:5
...

  Uninitialized value was created by an allocation of 'context.i' in the stack frame of function '_ZN8backward22TraceResolverLinuxImplINS_18trace_resolver_tag6libbfdEE7resolveENS_13ResolvedTraceE'
    #0 0x786610 in backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::resolve(backward::ResolvedTrace) /home/markus/dev/objectbox/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:1364
greenrobot commented 2 years ago

After suppressing the two above I get this:

Uninitialized bytes in __interceptor_strlen at offset 0 inside [0x7040000b4ac0, 58)
==421312==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x7fc1f4137b12  (/lib/x86_64-linux-gnu/libbfd-2.34-system.so+0x56b12)
    #1 0x7fc1f413943f in bfd_follow_build_id_debuglink (/lib/x86_64-linux-gnu/libbfd-2.34-system.so+0x5843f)
    #2 0x7fc1f4189082  (/lib/x86_64-linux-gnu/libbfd-2.34-system.so+0xa8082)
    #3 0x7fc1f418979e  (/lib/x86_64-linux-gnu/libbfd-2.34-system.so+0xa879e)
    #4 0x7fc1f41616fd in _bfd_elf_find_nearest_line (/lib/x86_64-linux-gnu/libbfd-2.34-system.so+0x806fd)
    #5 0x7925e0 in backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::find_in_section(unsigned long, unsigned long, backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::bfd_fileobject*, bfd_section*, backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::find_sym_result&) /home/markus/dev/objectbox/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:1716:22
    #6 0x7fc1f413aff6 in bfd_map_over_sections (/lib/x86_64-linux-gnu/libbfd-2.34-system.so+0x59ff6)
    #7 0x78b583 in backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::find_symbol_details(backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::bfd_fileobject*, void*, void*) /home/markus/dev/objectbox/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:1663:9
    #8 0x786e54 in backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::libbfd>::resolve(backward::ResolvedTrace) /home/markus/dev/objectbox/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:1444:9
    #9 0x794186 in void backward::Printer::print_stacktrace<backward::StackTrace const>(backward::StackTrace const&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&, backward::Colorize&) /home/markus/dev/objectbox/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:4041:33
    #10 0x78470d in std::__1::basic_ostream<char, std::__1::char_traits<char> >& backward::Printer::print<backward::StackTrace const>(backward::StackTrace const&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&) /home/markus/dev/objectbox/cbuild/Release-msan/objectbox/src/main/cpp/../../../../../../objectbox/src/main/cpp/external/backward/backward.hpp:4007:5
...
  Uninitialized value was created by a heap allocation
    #0 0x51c68d in malloc (/home/markus/dev/objectbox/cbuild/Release-msan/objectbox/src/main/cpp/objectbox-test+0x51c68d)
    #1 0x7fc1f4131f95  (/lib/x86_64-linux-gnu/libbfd-2.34-system.so+0x50f95)
greenrobot commented 2 years ago

Tried a couple of things to make backward work with memory sanitizer, but this is taking too long so I'm giving up. :sweat_smile:

I archived my changes here; maybe it's useful to someone: backward__futile_attempts_to_fix_msan.patch.txt

I did not dive deep and I wanted to clarify the following two diffed code sections:

-    if (!result.found && fobj->symtab) {
+    if (!result.found && fobj->symtab && *fobj->symtab) {

and

-    if (!result.found && fobj->dynamic_symtab) {
+    if (!result.found && fobj->dynamic_symtab && *fobj->dynamic_symtab) {

I did not see any output changes to the stack trace in both variants, but the variant checking the pointer to pointer additionally seemed less harmful to memory sanitizer. Ofc it depends on when things are initialized (which I did not want investigate further), but wanted still to ask to ensure it's not a bug in the current backward code. Someone more familiar with the code probably can tell right away.

bombela commented 2 years ago

I think it's libbfd. I have encounterd the same thing before. If you use another of the supported library. You might not observe this issue. At least for printing a stacktrace on a program crash it's alright. As the program is already doomed anyways.

atn34 commented 1 year ago

I ran into the same thing with libdwarf and libelf. libbfd is probably not instrumented with memory sanitizer, and memory sanitizer requires all code to be instrumented: https://clang.llvm.org/docs/MemorySanitizer.html#handling-external-code