llvm/llvm-project

[Bug] Assertion failed causing segfault on LLDB module python

sunn1day opened this issue · 3 comments

Describe the bug:
The assertion assert(hasVal); in getValue() at llvm/include/llvm/ADT/Optional.h:97 is reachable when the user runs in python lldb.SBDebugger.Terminate(), and then lldb.SBDebugger.Create().

T &getValue() &noexcept {
assert(hasVal);
return value;
}


Steps to reproduce the behavior:

  1. Get the llvm source code (commit ae8b10e) and compile it.
  2. run command: python3 poc_crash_lldb.py

POC


Output:

$ python3 poc_crash_lldb.py
python3: /dataZ/test_z3/ex7/llvm-project/llvm/include/llvm/ADT/Optional.h:97: T& llvm::optional_detail::OptionalStorage<T, <anonymous> >::getValue() & [with T = lldb_private::repro::Reproducer; bool <anonymous> = false]: Assertion `hasVal' failed.
Aborted (core dumped)
  • stack backtrace:
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007f41d413b921 in __GI_abort () at abort.c:79
#2  0x00007f41d412b48a in __assert_fail_base (fmt=0x7f41d42b2750 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x7f41c9bd9d01 "hasVal", file=file@entry=0x7f41c9bd9cc0 "/dataZ/test_z3/ex7/llvm-project/llvm/include/llvm/ADT/Optional.h", line=line@entry=97, function=function@entry=0x7f41c9bda020 <llvm::optional_detail::OptionalStorage<lldb_private::repro::Reproducer, false>::getValue() &::__PRETTY_FUNCTION__> "T& llvm::optional_detail::OptionalStorage<T, <anonymous> >::getValue() & [with T = lldb_private::repro::Reproducer; bool <anonymous> = false]") at assert.c:92
#3  0x00007f41d412b502 in __GI___assert_fail (assertion=0x7f41c9bd9d01 "hasVal", file=0x7f41c9bd9cc0 "/dataZ/test_z3/ex7/llvm-project/llvm/include/llvm/ADT/Optional.h", line=97, function=0x7f41c9bda020 <llvm::optional_detail::OptionalStorage<lldb_private::repro::Reproducer, false>::getValue() &::__PRETTY_FUNCTION__> "T& llvm::optional_detail::OptionalStorage<T, <anonymous> >::getValue() & [with T = lldb_private::repro::Reproducer; bool <anonymous> = false]") at assert.c:101
#4  0x00007f41c1c546f2 in llvm::optional_detail::OptionalStorage<lldb_private::repro::Reproducer, false>::getValue() & (this=0x7f41d2867ec0 <lldb_private::repro::Reproducer::InstanceImpl()::g_reproducer>) at /dataZ/test_z3/ex7/llvm-project/llvm/include/llvm/ADT/Optional.h:97
#5  0x00007f41c1c539bc in llvm::Optional<lldb_private::repro::Reproducer>::getValue() & (this=0x7f41d2867ec0 <lldb_private::repro::Reproducer::InstanceImpl()::g_reproducer>) at /dataZ/test_z3/ex7/llvm-project/llvm/include/llvm/ADT/Optional.h:280
#6  0x00007f41c1c52e36 in llvm::Optional<lldb_private::repro::Reproducer>::operator*() & (this=0x7f41d2867ec0 <lldb_private::repro::Reproducer::InstanceImpl()::g_reproducer>) at /dataZ/test_z3/ex7/llvm-project/llvm/include/llvm/ADT/Optional.h:287
#7  0x00007f41c1c51835 in lldb_private::repro::Reproducer::Instance () at /dataZ/test_z3/ex7/llvm-project/lldb/source/Utility/Reproducer.cpp:23
#8  0x00007f41c19a20e8 in lldb_private::CommandInterpreter::SetSynchronous (this=0x20b5ce0, value=false) at /dataZ/test_z3/ex7/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp:2769
#9  0x00007f41c199243e in lldb_private::CommandInterpreter::CommandInterpreter (this=0x20b5ce0, debugger=..., synchronous_execution=false) at /dataZ/test_z3/ex7/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp:135
#10 0x00007f41c1816aa1 in std::make_unique<lldb_private::CommandInterpreter, lldb_private::Debugger&, bool> () at /usr/include/c++/7/bits/unique_ptr.h:821
#11 0x00007f41c180cb89 in lldb_private::Debugger::Debugger (this=0x20b0f40, log_callback=0x0, baton=0x0) at /dataZ/test_z3/ex7/llvm-project/lldb/source/Core/Debugger.cpp:757
#12 0x00007f41c180c0fa in lldb_private::Debugger::CreateInstance (log_callback=0x0, baton=0x0) at /dataZ/test_z3/ex7/llvm-project/lldb/source/Core/Debugger.cpp:653
#13 0x00007f41c157af24 in lldb::SBDebugger::Create (source_init_files=false, callback=0x0, baton=0x0) at /dataZ/test_z3/ex7/llvm-project/lldb/source/API/SBDebugger.cpp:263
#14 0x00007f41c157ad8d in lldb::SBDebugger::Create () at /dataZ/test_z3/ex7/llvm-project/lldb/source/API/SBDebugger.cpp:238
#15 0x00007f41c16d026b in _wrap_SBDebugger_Create__SWIG_0 (args=0x7f41d46c7048) at tools/lldb/bindings/python/LLDBWrapPython.cpp:21722
#16 0x00007f41c16d0787 in _wrap_SBDebugger_Create (self=0x7f41d28f6f98, args=0x7f41d46c7048) at tools/lldb/bindings/python/LLDBWrapPython.cpp:21817

@llvm/issue-subscribers-lldb

FWIW, a lot of SB API functions will assert when calling them after Terminate was called. But the assert/error here should really be better than this.

Raphael is correct. You must call SBDebugger::Initialize again after calling SBDebugger::Terminate. Unless the issue reproduces after the initialize call I would say that this behaves as expected.

Regarding the error message, it should be straightforward to track this in the debugger and print a better error message.