llvm / llvm/llvm-project

[LLDB] Calling `SBDebugger.Terminate()` within LLDB's python interpreter causes LLDB to hang forever

Open
#190,516 3 comments 0 reactions 0 assignees View on GitHub
hang lldb
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

```
(lldb) version
lldb version 22.1.2 (https://github.com/llvm/llvm-project revision 1ab49a973e210e97d61e5db6557180dcb92c3e98)
clang revision 1ab49a973e210e97d61e5db6557180dcb92c3e98
llvm revision 1ab49a973e210e97d61e5db6557180dcb92c3e98

(lldb) script import sys; sys.version
'3.11.2 (tags/v3.11.2:878ead1, Feb 7 2023, 16:38:35) [MSC v.1934 64 bit (AMD64)]'
```

Encountered when running Rust's debug info test suite. The test runner code is [here](https://github.com/rust-lang/rust/blob/e73c56abd0baf3dbaafbdc3ce6072a416aade867/src/etc/lldb_batchmode.py#L192). It basically takes a file with a bunch of commands, executes them, and then we analyze the output.. An example of a file would be:

```
breakpoint set --file 'vec.rs' --line 33
run
v a
quit
```

Basically, we create an `SBDebugger` *within* the script (even though we could theoretically use `lldb.SBDebugger`) because LLDB doesn't update the outer REPL state (e.g. currently running process, currently selected frame, etc.) while executing commands from the `HandleCommand` API. That means even though we can register and stop on breakpoints, we can't use `HandleCommand` to inspect the frame variables, which we need to do for the tests (i know there's better ways to do that, but it is what it is for now).

My understanding is that `lldb.debugger` is the `SBDebugger` object owned by the REPL, the one we spawn is owned by the python script, and `Terminate()`'s job is to [gracefully kill *lldb.exe*, not just the `SBDebugger` object.](https://lldb.llvm.org/python_api/lldb.SBDebugger.html#lldb.SBDebugger.Terminate)

Weirdly, calling `lldb.debugger.Terminate()` *doesn't* hang forever, but instead throws and exception regarding `None` objects not having a `.Terminate()`. Even weirder, trying a minimal example standalone *does* hang forever?

```txt
> lldb
(lldb) script lldb.debugger.Terminate()
// hangs forever
```

Contributor guide

Open the contributing guide

Research direction

Reproduce the minimal `lldb.debugger.Terminate()` hang, then compare it with the nested `SBDebugger` flow in Rust's `src/etc/lldb_batchmode.py` around line 192. Trace the `SBDebugger.Terminate` and `HandleCommand` entry points, and verify that termination no longer hangs when called from LLDB's Python interpreter.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.