llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.96k stars 11.94k forks source link

lldb crash in lldb_private::Address::Address(lldb_private::Address const&) copy constructor #53427

Open dmlary opened 2 years ago

dmlary commented 2 years ago

Using lldb-13.0.0 on x86_64, debugging a powerpc target via gdb-remote, encountered a crash while running thread until <addr>.

(lldb) th until 0x4000068c
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0.  Program arguments: lldb ./build/bin/some_utility
 #0 0x00000000004e0857 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /work/llvm/lib/Support/Unix/Signals.inc:565:0
 #1 0x00000000004e090e PrintStackTraceSignalHandler(void*) /work/llvm/lib/Support/Unix/Signals.inc:632:0
 #2 0x00000000004de8de llvm::sys::RunSignalHandlers() /work/llvm/lib/Support/Signals.cpp:97:0
 #3 0x00000000004e029b SignalHandler(int) /work/llvm/lib/Support/Unix/Signals.inc:407:0
 #4 0x00007f5551bea630 __restore_rt sigaction.c:0:0
 #5 0x00007f5546b86e18 std::__weak_ptr<lldb_private::Section, (__gnu_cxx::_Lock_policy)2>::__weak_ptr(std::__weak_ptr<lldb_private::Section, (__gnu_cxx::_Lock_policy)2> const&) /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr_base.h:1607:0
 #6 0x00007f5546b86e63 std::weak_ptr<lldb_private::Section>::weak_ptr(std::weak_ptr<lldb_private::Section> const&) /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/shared_ptr.h:540:0
 #7 0x00007f5546b86e89 lldb_private::Address::Address(lldb_private::Address const&) /work/lldb/include/lldb/Core/Address.h:128:0
 #8 0x00007f5546d79a41 lldb_private::AddressRange::AddressRange(lldb_private::AddressRange const&) /work/lldb/include/lldb/Core/AddressRange.h:25:0
 #9 0x00007f554883fc98 CommandObjectThreadUntil::DoExecute(lldb_private::Args&, lldb_private::CommandReturnObject&) /work/lldb/source/Commands/CommandObjectThread.cpp:973:0
#10 0x00007f55473ed9d3 lldb_private::CommandObjectParsed::Execute(char const*, lldb_private::CommandReturnObject&) /work/lldb/source/Interpreter/CommandObject.cpp:995:0
#11 0x00007f55473c10c9 lldb_private::CommandInterpreter::HandleCommand(char const*, lldb_private::LazyBool, lldb_private::CommandReturnObject&) /work/lldb/source/Interpreter/CommandInterpreter.cpp:1790:0
#12 0x00007f55473c56be lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&, std::string&) /work/lldb/source/Interpreter/CommandInterpreter.cpp:2851:0
#13 0x00007f554729be5d lldb_private::IOHandlerEditline::Run() /work/lldb/source/Core/IOHandler.cpp:579:0
#14 0x00007f554725f8bb lldb_private::Debugger::RunIOHandlers() /work/lldb/source/Core/Debugger.cpp:880:0
#15 0x00007f55473c689c lldb_private::CommandInterpreter::RunCommandInterpreter(lldb_private::CommandInterpreterRunOptions&) /work/lldb/source/Interpreter/CommandInterpreter.cpp:3096:0
#16 0x00007f5546cb48e8 lldb::SBDebugger::RunCommandInterpreter(bool, bool) /work/lldb/source/API/SBDebugger.cpp:1214:0
#17 0x000000000040b6b5 Driver::MainLoop() /work/lldb/tools/driver/Driver.cpp:680:0
#18 0x000000000040c61d main /work/lldb/tools/driver/Driver.cpp:944:0
#19 0x00007f5544ada545 __libc_start_main (/lib64/libc.so.6+0x22545)
#20 0x0000000000408f45 _start (/usr/local/llvm-13.0.0/bin/lldb+0x408f45)

backtrace in the corefile is a little different:

(lldb) bt
* thread #1, name = 'lldb', stop reason = signal SIGSEGV
    frame #0: 0x00007f5546b86e18 liblldb.so.13`std::__weak_ptr<lldb_private::Section, (__gnu_cxx::_Lock_policy)2>::__weak_ptr(this=0x00007fffdfdf97a0, (null)=0x00000000000000a8)2> const&) at shared_ptr_base.h:1607
    frame #1: 0x00007f5546b86e63 liblldb.so.13`std::weak_ptr<lldb_private::Section>::weak_ptr(this=0x00007fffdfdf97a0, (null)=nullptr) at shared_ptr.h:540
    frame #2: 0x00007f5546b86e89 liblldb.so.13`lldb_private::Address::Address(this=0x00007fffdfdf97a0, rhs=0x00000000000000a8) at Address.h:128
    frame #3: 0x00007f5546d79a41 liblldb.so.13`lldb_private::AddressRange::AddressRange(this=0x00007fffdfdf97a0, (null)=0x00000000000000a8) at AddressRange.h:25
  * frame #4: 0x00007f554883fc98 liblldb.so.13`CommandObjectThreadUntil::DoExecute(this=0x00000000019f7eb0, command=0x00007fffdfdf9be0, result=0x00007fffdfdf9f60) at CommandObjectThread.cpp:972
    frame #5: 0x00007f55473ed9d3 liblldb.so.13`lldb_private::CommandObjectParsed::Execute(this=0x00000000019f7eb0, args_string="0x4000068c", result=0x00007fffdfdf9f60) at CommandObject.cpp:995
    frame #6: 0x00007f55473c10c9 liblldb.so.13`lldb_private::CommandInterpreter::HandleCommand(this=0x00000000019b6680, command_line="th until 0x4000068c", lazy_add_to_history=eLazyBoolCalculate, result=0x00007fffdfdf9f60) at CommandInterpreter.cpp:1804
    frame #7: 0x00007f55473c56be liblldb.so.13`lldb_private::CommandInterpreter::IOHandlerInputComplete(this=0x00000000019b6680, io_handler=0x0000000001aee8f0, line="th until 0x4000068c") at CommandInterpreter.cpp:2848
    frame #8: 0x00007f554729be5d liblldb.so.13`lldb_private::IOHandlerEditline::Run(this=0x0000000001aee8f0) at IOHandler.cpp:579
    frame #9: 0x00007f554725f8bb liblldb.so.13`lldb_private::Debugger::RunIOHandlers(this=0x00000000019b4b30) at Debugger.cpp:877
    frame #10: 0x00007f55473c689c liblldb.so.13`lldb_private::CommandInterpreter::RunCommandInterpreter(this=0x00000000019b6680, options=0x00007fffdfdfa2e0) at CommandInterpreter.cpp:3094
    frame #11: 0x00007f5546cb48e8 liblldb.so.13`lldb::SBDebugger::RunCommandInterpreter(this=0x00007fffdfdfa5f0, auto_handle_events=true, spawn_thread=false) at SBDebugger.cpp:1214
    frame #12: 0x000000000040b6b5 lldb`Driver::MainLoop(this=0x00007fffdfdfa5d0) at Driver.cpp:676
    frame #13: 0x000000000040c61d lldb`main(argc=2, argv=0x00007fffdfdfab18) at Driver.cpp:944
    frame #14: 0x00007f5544ada545 libc.so.6`__libc_start_main + 245
    frame #15: 0x0000000000408f45 lldb`_start + 41
llvmbot commented 2 years ago

@llvm/issue-subscribers-bug

llvmbot commented 2 years ago

@llvm/issue-subscribers-lldb

JDevlieghere commented 2 years ago

We're actually crashing in the Address copy constructor. llvm::sys::PrintStackTrace is what prints the little stack trace in the console and gets called from the signal handler. It appears like we're crashing when copy-constructing the m_section_wp weak pointer.

dmlary commented 2 years ago

You're right! I should have pieced that together.

For a little more background, this is happening during some dll lazy-loading function stubs. They work, but they do perform some questionable actions on the stack to allow the original function call arguments to get passed to the dll function once the dll has been opened and the address looked up.

Looking at the coredump (with C, not C++ experience), this is the only frame in the backtrace I see anything vaguely intersting, sc.function == nullptr going into GetAddressRange():

frame #4: 0x00007f554883fc98 liblldb.so.13`CommandObjectThreadUntil::DoExecute(this=0x00000000019f7eb0, command=0x00007fffdfdf9be0, result=0x00007fffdfdf9f60) at CommandObjectThread.cpp:972
   969          std::vector<addr_t> address_list;
   970
   971          // Find the beginning & end index of the
-> 972          AddressRange fun_addr_range = sc.function->GetAddressRange();
   973          Address fun_start_addr = fun_addr_range.GetBaseAddress();
   974          line_table->FindLineEntryByAddress(fun_start_addr, function_start,
   975                                             &index_ptr);
(lldb) p sc
(lldb_private::SymbolContext) $0 = {
  target_sp = std::__shared_ptr<lldb_private::Target, 4>::element_type @ 0x0000000001ad2c10 {
    _M_ptr = 0x0000000001ad2c10
  }
  module_sp = std::__shared_ptr<lldb_private::Module, 4>::element_type @ 0x0000000001ad74c0 {
    _M_ptr = 0x0000000001ad74c0
  }
  comp_unit = 0x0000000001b68f30
  function = nullptr
  block = nullptr
  line_entry = {
    range = {
      m_base_addr = {
        m_section_wp = std::__weak_ptr<lldb_private::Section, 4>::element_type @ 0x0000000001acf0d0 {
          _M_ptr = 0x0000000001acf0d0
        }
        m_offset = 1548
      }
      m_byte_size = 4
    }
    file = {
      m_directory = (m_string = "/tmp/XXXX.stub2762")
      m_filename = (m_string = "__lib_XXXXXXXXXXXXXXX_stub_gen.s")
      m_is_resolved = false
      m_style = posix
    }
    original_file = {
      m_directory = (m_string = "/tmp/XXXX.stub2762")
      m_filename = (m_string = "__lib_XXXXXXXXXXXXXXX_stub_gen.s")
      m_is_resolved = false
      m_style = posix
    }
    line = 61
    column = 0
    is_start_of_statement = 1
    is_start_of_basic_block = 0
    is_prologue_end = 0
    is_epilogue_begin = 0
    is_terminal_entry = 0
  }
  symbol = 0x0000000001aff7e8
  variable = nullptr
}
jimingham commented 2 years ago

lldb expects that if you are stopped in a frame with debug information we should be able to make a function object, so we don't check that the function is valid. I put up:

https://reviews.llvm.org/D119297

for review, that just checks that we actually have a function before accessing it, and returns an error from "thread until".