556 Commits
Author SHA1 Message Date
David Spickett 517e48db31 [lldb] Return llvm::Error from EnableLogChannel (#206479)
Instead of a boolean plus writing errors to a stream.

llvm::Error is either success or an error message, unlike
before where we could (and did sometimes) succeed but 
also have an error message.

We can do this for DisableLogChannel too but 
I'll do that in a follow up.
2026-07-01 14:59:55 +01:00
Raphael Isemann 2902b031f0 [lldb] Add tab-mode to autosuggestion feature (#206728) 2026-06-30 16:42:24 +01:00
Jonas Devlieghere a873660edf [lldb] Collect a diagnostics bundle on the Diagnostics class (#206189)
Add Diagnostics::Collect, which gathers the state a triager needs into a
directory, best-effort (one failed section never sinks the rest): the
always-on log plus the debugger's file logs, statistics.json from
DebuggerStats, and a snapshot of the commands run first when triaging
(target list, image list, thread list, backtraces, image lookup, frame
variable).

It returns a Diagnostics::Report with the LLDB version, host, and how
LLDB was invoked, plus an Attachments holding the bundle directory and
the files written into it. Each file is recorded as it is written, so a
file that could not be created is simply absent from the list. The
report is expected to grow more fields over time.

`diagnostics dump` now calls Collect and prints the report as JSON to
the terminal instead of only reporting where the directory was written.
Here's what this all looks like:

```
(lldb) diagnostics dump
{
  "attachments": {
    "directory": "/var/folders/6b/3sb80ks56rz5vwlhsdvpsxmh0000gn/T/diagnostics-4b5e9f",
    "files": [
      "diagnostics.log",
      "statistics.json",
      "commands.txt"
    ]
  },
  "invocation": "./build/bin/count",
  "os": "arm64-apple-macosx platform=host os=27.0 build=26A374",
  "version": "lldb version 23.0.0git (git@github.com:llvm/llvm-project.git revision 85fa95f05bc5f0c6b4fd845141e522cd4b9589d7)\n  clang revision 85fa95f05bc5f0c6b4fd845141e522cd4b9589d7\n  llvm revision 85fa95f05bc5f0c6b4fd845141e522cd4b9589d7"
}
```

This is in preparation for a future PR which adds the ability to take
all this information and pre-fill a bug report with it.
2026-06-29 13:09:32 -07:00
Jonas Devlieghere 9f34f1caf5 [lldb] Remove the Diagnostics callback mechanism (#206132)
The Diagnostics framework had a callback registry (AddCallback /
RemoveCallback) so subsystems could contribute files to a diagnostics
directory, intended to also run during crash handling. That crash-time
path never materialized, and the sole registered callback was the
Debugger copying its file-backed logs. If you had no logging enabled,
the directory would be empty, confusing the users.

Remove the registry and the callback loop in Diagnostics::Create (which
now just writes the in-memory log), and expose the log copying as
Debugger::CopyLogFilesToDirectory, which "diagnostics dump" calls
directly. The dump command now copies the invoking debugger's logs
rather than every debugger's, which is the more useful behavior I want
to double down on.
2026-06-26 10:49:55 -07:00
Jonas Devlieghere 9aef315020 [lldb] Add SBDebugger::SetTerminalDimensions to set width and height atomically (#201965)
Terminal width and height were communicated to the debugger separately,
via SetTerminalWidth() and SetTerminalHeight(). Each notified the
IOHandler and the statusline, so on a resize they recomputed their
layout twice: once with one dimension updated and the other still stale.

Add Debugger::SetTerminalDimensions(width, height) (exposed through
SBDebugger) that updates both properties before notifying, and
reimplement the single-axis setters and the driver's resize handler in
terms of it.

Also fix SBDebugger::GetTerminalHeight(), which returned the width.
2026-06-06 09:26:32 -07:00
Jonas Devlieghere ec2c6fb42b [lldb] Move GetSelectedTarget from Debugger to CommandInterpreter (NFC) (#197805)
The notion of a "selected target" is something that belongs at the
command layer rather than the debugger layer. Jim and I were discussing
how this is a foot-gun and I suggested moving it into the
CommandInterpreter. Everyone else that needs to get their hands on the
current target should do so through the execution context. The latter is
trivial to swap out if the "selected one" isn't what you should be
operating on.
2026-05-15 11:09:20 -07:00
Ebuka Ezike eeffaf8a22 Revert "Fix for #177160 : [lldb] Real-time console pane for output in lldb tui (#197473) (#197884)
This reverts commit cd25475854.

This test is timing out on GreenDragon
(https://ci.swift.org/view/all/job/llvm.org/job/as-lldb-cmake/42857/)

the PR https://github.com/llvm/llvm-project/pull/197473
2026-05-15 10:15:57 +01:00
Nagesh Nazare cd25475854 Fix for #177160 : [lldb] Real-time console pane for output in lldb tui (#197473)
This Change:
The stalling testcase in the PR: #177160  has been fixed.

- The cause of it was that the test required to get line 0 & line 99
from the console output with auto-scroll on. With limited display area,
this test was unreliable and impossible to achieve - which caused it to
wait / hang there.

Original Change : 

New Console Pane that -
- captures stdout/stderr msgs from debugged process
- displays output to console in real-time
- provides scrolling and navigation features
- manages 10K line circular buffer
- auto-scroll on/off feature

<img width="2940" height="1744" alt="image"
src="https://github.com/user-attachments/assets/49e9dd3e-9f6f-4383-820b-ce365a46208f"
/>

Controls -
enable / disable : F5 + o
tab to switch to Console pane
UP/ DOWN / PAGEUP/ PAGEDOWN for scrolling,
HOME/ END for top or bottom
c for clear output
2026-05-14 16:30:22 +01:00
David Spickett 0bdf71d5a6 Revert "[lldb] Real-time console pane for output in lldb tui" (#196507)
Reverts llvm/llvm-project#177160

The new test is timing out on the AArch64 Linux buildbot
(https://lab.llvm.org/buildbot/#/builders/59/builds/34166) and on my own
machine.

I suspect something to do with the requested terminal size. If what we
get is smaller than requested, it could time out waiting for expected
program output.
2026-05-08 11:16:15 +01:00
Nagesh Nazare 7578a9ad93 [lldb] Real-time console pane for output in lldb tui (#177160)
Creating a feature branch.

New Console Pane that -

- captures stdout/stderr msgs from debugged process
- displays output to console in real-time
- provides scrolling and navigation features
- manages 10K line circular buffer
- auto-scroll on/off feature

<img width="2940" height="1744" alt="image"
src="https://github.com/user-attachments/assets/49e9dd3e-9f6f-4383-820b-ce365a46208f"
/>

Controls -
enable / disable : F5 + o
tab to switch to Console pane
UP/ DOWN / PAGEUP/ PAGEDOWN for scrolling,
HOME/ END for top or bottom
c for clear output

Tested on Mac
2026-05-07 10:46:42 -07:00
Michael Buch 404b75651f [lldb][Target] Move Debugger::GetSafeAutoLoadPaths into Target (#192703)
Required for https://github.com/llvm/llvm-project/pull/191454

We want to make the `Target`/`Platform` define commonly used default
paths (without configuring them in CMake). This is easiest if this logic
lived in `Target` (since then we have access to the associated
`Platform`).
2026-04-19 06:54:45 +01:00
Jonas Devlieghere 029abe6730 [lldb] Store the dummy target in the selected execution context (#190496)
Store the dummy target in the selected execution context. There's no
reason for everybody to have to independently fall back to the dummy
target.
2026-04-17 18:29:08 -07:00
Jonas DevlieghereandJim Ingham e8c8cbb06a [lldb] Don't adopt in the ExecutionContext from auto-continue events (#191433)
When a breakpoint auto-continues, the event handler receives a "stopped
but restarted" event. During the transition where we step over the
breakpoint (before continuing), the public state hasn't yet been set to
running. This caused the `DefaultEventHandler` to call
`ExecutionContextRef` with `adopt_selected=true`, which would fetch
stale thread/frame state and needlessly (and incorrectly) interrupt the
target to compute the execution context (used by the statusline). This
PR fixes that by not doing that.

Fixes #190956

Co-authored-by: Jim Ingham <jingham@apple.com>
2026-04-17 10:05:08 -07:00
GeorgeHuyuboandGeorge Hu 02fdc8f8de [lldb] Fix stale Symbol pointer crash in statusline after 'target symbols add' (#188377)
Context: 
lldb might crash when running to a debuggee crashing state and do a
target symbols add command.
Backtrace: 
```
 #0 0x000055ca6790dc65 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/hyubo/osmeta/external/llvm-project/llvm/lib/Support/Unix/Signals.inc:848:11
 #1 0x000055ca6790e434 PrintStackTraceSignalHandler(void*) /home/hyubo/osmeta/external/llvm-project/llvm/lib/Support/Unix/Signals.inc:931:1
 #2 0x000055ca6790b839 llvm::sys::RunSignalHandlers() /home/hyubo/osmeta/external/llvm-project/llvm/lib/Support/Signals.cpp:104:5
 #3 0x000055ca6790ff6b SignalHandler(int, siginfo_t*, void*) /home/hyubo/osmeta/external/llvm-project/llvm/lib/Support/Unix/Signals.inc:430:38
 #4 0x00007fe9e5e44560 __restore_rt /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/signal/../sysdeps/unix/sysv/linux/libc_sigaction.c:13:0
 #5 0x00007fe9e5f25649 syscall /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/misc/../sysdeps/unix/sysv/linux/x86_64/syscall.S:38:0
 #6 0x00007fe9ec649170 SignalHandler(int, siginfo_t*, void*) /home/hyubo/osmeta/external/llvm-project/llvm/lib/Support/Unix/Signals.inc:429:7
 #7 0x00007fe9e5e44560 __restore_rt /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/signal/../sysdeps/unix/sysv/linux/libc_sigaction.c:13:0
 #8 0x00007fe9ebb77bf0 lldb_private::operator<(lldb_private::StackID const&, lldb_private::StackID const&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Target/StackID.cpp:99:16
 #9 0x00007fe9ebb6863d CompareStackID(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Target/StackFrameList.cpp:683:3
#10 0x00007fe9ebb6d049 bool __gnu_cxx::__ops::_Iter_comp_val<bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)>::operator()<__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID const>(__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID const&) /mnt/gvfs/third-party2/libgcc/d1129753c8361ac8e9453c0f4291337a4507ebe6/11.x/platform010/5684a5a/include/c++/11.x/bits/predefined_ops.h:196:4
#11 0x00007fe9ebb6cefe __gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>> std::__lower_bound<__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID, __gnu_cxx::__ops::_Iter_comp_val<bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)>>(__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, __gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID const&, __gnu_cxx::__ops::_Iter_comp_val<bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)>) /mnt/gvfs/third-party2/libgcc/d1129753c8361ac8e9453c0f4291337a4507ebe6/11.x/platform010/5684a5a/include/c++/11.x/bits/stl_algobase.h:1464:8
#12 0x00007fe9ebb6cdfc __gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>> std::lower_bound<__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID, bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)>(__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, __gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID const&, bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)) /mnt/gvfs/third-party2/libgcc/d1129753c8361ac8e9453c0f4291337a4507ebe6/11.x/platform010/5684a5a/include/c++/11.x/bits/stl_algo.h:2062:14
#13 0x00007fe9ebb685fa auto llvm::lower_bound<std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>&, lldb_private::StackID const&, bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)>(std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>&, lldb_private::StackID const&, bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)) /home/hyubo/osmeta/external/llvm-project/llvm/include/llvm/ADT/STLExtras.h:2001:10
#14 0x00007fe9ebb68441 lldb_private::StackFrameList::GetFrameWithStackID(lldb_private::StackID const&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Target/StackFrameList.cpp:697:11
#15 0x00007fe9ebbee395 lldb_private::Thread::GetFrameWithStackID(lldb_private::StackID const&) /home/hyubo/osmeta/external/llvm-project/lldb/include/lldb/Target/Thread.h:459:7
#16 0x00007fe9ebac7cf7 lldb_private::ExecutionContextRef::GetFrameSP() const /home/hyubo/osmeta/external/llvm-project/lldb/source/Target/ExecutionContext.cpp:643:25
#17 0x00007fe9ebac80e1 lldb_private::GetStoppedExecutionContext(lldb_private::ExecutionContextRef const*) /home/hyubo/osmeta/external/llvm-project/lldb/source/Target/ExecutionContext.cpp:164:34
#18 0x00007fe9eb8903fa lldb_private::Statusline::Redraw(std::optional<lldb_private::ExecutionContextRef>) /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/Statusline.cpp:139:7
#19 0x00007fe9eb7ac8be lldb_private::Debugger::RedrawStatusline(std::optional<lldb_private::ExecutionContextRef>) /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/Debugger.cpp:1233:3
#20 0x00007fe9eb804d1e lldb_private::IOHandlerEditline::RedrawCallback() /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/IOHandler.cpp:446:3
#21 0x00007fe9eb80aa81 lldb_private::IOHandlerEditline::IOHandlerEditline(lldb_private::Debugger&, lldb_private::IOHandler::Type, std::shared_ptr<lldb_private::File> const&, std::shared_ptr<lldb_private::LockableStreamFile> const&, std::shared_ptr<lldb_private::LockableStreamFile> const&, unsigned int, char const*, llvm::StringRef, llvm::StringRef, bool, bool, unsigned int, lldb_private::IOHandlerDelegate&)::$_2::operator()() const /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/IOHandler.cpp:262:73
#22 0x00007fe9eb80aa5d void llvm::detail::UniqueFunctionBase<void>::CallImpl<lldb_private::IOHandlerEditline::IOHandlerEditline(lldb_private::Debugger&, lldb_private::IOHandler::Type, std::shared_ptr<lldb_private::File> const&, std::shared_ptr<lldb_private::LockableStreamFile> const&, std::shared_ptr<lldb_private::LockableStreamFile> const&, unsigned int, char const*, llvm::StringRef, llvm::StringRef, bool, bool, unsigned int, lldb_private::IOHandlerDelegate&)::$_2>(void*) /home/hyubo/osmeta/external/llvm-project/llvm/include/llvm/ADT/FunctionExtras.h:213:5
#23 0x00007fe9eb93bfbf llvm::unique_function<void ()>::operator()() /home/hyubo/osmeta/external/llvm-project/llvm/include/llvm/ADT/FunctionExtras.h:365:5
#24 0x00007fe9eb93bb80 lldb_private::Editline::GetCharacter(wchar_t*) /home/hyubo/osmeta/external/llvm-project/lldb/source/Host/common/Editline.cpp:0:5
#25 0x00007fe9eb941a18 lldb_private::Editline::ConfigureEditor(bool)::$_0::operator()(editline*, wchar_t*) const /home/hyubo/osmeta/external/llvm-project/lldb/source/Host/common/Editline.cpp:1287:5
#26 0x00007fe9eb9419e2 lldb_private::Editline::ConfigureEditor(bool)::$_0::__invoke(editline*, wchar_t*) /home/hyubo/osmeta/external/llvm-project/lldb/source/Host/common/Editline.cpp:1286:27
#27 0x00007fe9f3384e26 el_getc /home/engshare/third-party2/libedit/3.1/src/libedit/src/read.c:439:14
#28 0x00007fe9f3384e26 el_getc /home/engshare/third-party2/libedit/3.1/src/libedit/src/read.c:400:1
#29 0x00007fe9f3384f90 read_getcmd /home/engshare/third-party2/libedit/3.1/src/libedit/src/read.c:247:14
#30 0x00007fe9f3384f90 el_gets /home/engshare/third-party2/libedit/3.1/src/libedit/src/read.c:586:14
#31 0x00007fe9eb9409f3 lldb_private::Editline::GetLine(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, bool&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Host/common/Editline.cpp:1636:16
#32 0x00007fe9eb8044d7 lldb_private::IOHandlerEditline::GetLine(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, bool&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/IOHandler.cpp:339:5
#33 0x00007fe9eb805609 lldb_private::IOHandlerEditline::Run() /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/IOHandler.cpp:600:11
#34 0x00007fe9eb7b214c lldb_private::Debugger::RunIOHandlers() /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/Debugger.cpp:1280:16
#35 0x00007fe9eb98f00f lldb_private::CommandInterpreter::RunCommandInterpreter(lldb_private::CommandInterpreterRunOptions&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp:3620:16
#36 0x00007fe9eb4f0e09 lldb::SBDebugger::RunCommandInterpreter(bool, bool) /home/hyubo/osmeta/external/llvm-project/lldb/source/API/SBDebugger.cpp:1234:42
#37 0x000055ca6788d6b0 Driver::MainLoop() /home/hyubo/osmeta/external/llvm-project/lldb/tools/driver/Driver.cpp:677:3
#38 0x000055ca6788e226 main /home/hyubo/osmeta/external/llvm-project/lldb/tools/driver/Driver.cpp:887:17
#39 0x00007fe9e5e2c657 __libc_start_call_main /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#40 0x00007fe9e5e2c718 call_init /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/csu/../csu/libc-start.c:128:20
#41 0x00007fe9e5e2c718 __libc_start_main@GLIBC_2.2.5 /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/csu/../csu/libc-start.c:379:5
#42 0x000055ca67889a11 _start /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/csu/../sysdeps/x86_64/start.S:118:0
Segmentation fault (core dumped)
```

When `target symbols add` is run, `Symtab::AddSymbol()` can reallocate
the underlying `std::vector<Symbol>` and resize it, invalidating all
existing Symbol* pointers. While `Process::Flush()` clears stale stack
frames, the statusline caches its own `ExecutionContextRef` containing a
`StackID` with a `SymbolContextScope*` (which can be a `Symbol*`). This
cached reference is not cleared by `Process::Flush()`, so the next
statusline redraw accesses a dangling pointer and crashes.

Fix this by adding `Statusline::Flush()` which clears the cached frame,
`Debugger::Flush()` which forwards to it under the statusline mutex, and
calling `Debugger::Flush()` from `Process::Flush()` so that all flush
paths (symbol add, exec, module load) also invalidate the statusline's
stale state.

After this fix, lldb is not crashing anymore, new symbols from a symbol
file are correctly loaded

---------

Co-authored-by: George Hu <georgehuyubo@gmail.com>
2026-04-15 11:43:07 -07:00
Alex Langford 3dfa021578 [lldb][NFC] Stop using ConstStrings with BroadcastEventSpec (#190660)
BroadcastEventSpec owns the broadcaster class its configured to listen
for. Broadcasters usually advertise their broadcast class name with
StringRefs so there's no need to put them in the string pool.

The only exception here is SBListener. There are 2 methods that take
`const char *` values. However, that's handled when converting them to
StringRefs.
2026-04-07 11:04:02 -07:00
Michael Buch 116b045b1e [lldb] Make argument to ConstString::AsCString explicit (#190183)
This patch makes the default parameter to ConstString::AsCString
explicit. Currently it defaults to `nullptr`. However, there a bunch of
callsites that do `printf("%s", foo.AsCString())`, which is UB (I have
at least 1 crash on me where this was the root cause).

Alternatively we could change the default to `""` instead of `nullptr`,
but code that did `if (foo.AsCString())` would then change meaning.

Command I ran to generate this patch:
```
rg "\.AsCString\(\)" lldb -l | xargs sed -i '' 's/\.AsCString()/.AsCString(nullptr)/g'
```

There's also a commonly used `Status::AsCString` with a default
parameter. So I added a temporary:
```
const char *AsCString(std::nullptr_t) const = delete;
```
overload to `Status`, and fixed all the compile errors.

In a follow-up PR I intend to change the callsites that do `printf("%s",
foo.AsCString(nullptr)` to pass `""` as the fallback parameter. Another
dangrous pattern is `std::string(error.AsCString(nullptr))`

rdar://171219173
2026-04-07 13:39:48 +00:00
Michael Buch 0ec9f7ebbd [lldb] Add mechanism for auto-loading Python scripts from pre-configured paths (#187031)
Depends on:
* https://github.com/llvm/llvm-project/pull/187229

(only second commit and onwards are relevant)

This patch implements the base infrastructure described in this [RFC re.
Moving libc++ data-formatters out of
LLDB](https://discourse.llvm.org/t/rfc-lldb-moving-libc-data-formatters-out-of-lldb/89591)

The intention is to provide vendors with a way to pre-configure a set of
paths that LLDB can automatically ingest formatter scripts from.

Three main changes:
1. Adds a CMake variable `LLDB_SAFE_AUTO_LOAD_PATHS` which is a
semi-colon separated list of paths. This is intended to be set by
vendors when building LLDB for distribution.
2. Adds a setting that only exists in asserts mode called
`testing.safe-auto-load-paths` which allows setting the paths without a
CMake configuration. Used for local development and, more crucially, the
shell and unit tests
3. Adds a `LocateScriptingResourcesFromSafePaths` which
`Platform::LocateExecutableScriptingResources` calls by default (and
hence used by all platforms). I add a
`LocateExecutableScriptingResourcesImpl` that platforms can override if
they have platform-specific resource script locations (e.g., dSYMs on
Darwin).

Whenever we load an image, we check the safe path (starting with the
last appended path) for a directory called
`/safe/path/to/<module>/<module>.py`. If such script exists, we import
it as a Python module. If not, we move on to the next safe path.

Currently the default for `LLDB_SAFE_AUTO_LOAD_PATHS` is empty.
Eventually the plan is to make those point to the libc++ installation
(where the formatters will live) depending on platform/vendor. For macOS
we'll add a special `$SDK_ROOT` that can be used in the path variable,
which `LocateScriptingResourcesFromSafePaths` will resolve to an actual
SDK path.

*AI Usage*:
* Claude assisted with the CMake machinery which I then reviewed and
cleaned up. I'm not sure this is the most idiomatic way of letting a
user provide lists of paths, but I couldn't find a better way.
* Wrote the basic auto-load Shell tests myself and asked claude to stamp
out a bunch more for different scenarios. Reviewed and cleaned those up
myself.
2026-03-21 00:22:34 +00:00
Michael Buch 361987c01a [lldb][Module] Remove feedback_stream parameter from LoadScriptingResources (#186787)
I'm in the process of making `LoadScriptingResources` interactively ask
a user whether to load a script. I'd like to turn the existing warning
into the prompt. The simplest way to achieve this is to not print into a
`feedback_stream` parameter, and instead create a prompt right there.
This patch removes the `feedback_stream` parameter and emits a
`ReportWarning` instead. If we get around to adding the prompt instead
of the warning, those changes will be simpler to review. But even if we
don't end up replacing the warning with a prompt, moving away from
output parameters and towards more structured error reporting is a
nice-to-have (e.g., the `warning` prefix is now colored, IDEs have more
flexibility on how to present the warning, etc.).

For a command-line user nothing should change with this patch (apart
from `warning:` being highlighted).
2026-03-16 15:18:23 +00:00
Jonas Devlieghere 4ad2c5356d [lldb] Turn on OSC 9;4 graphical progress in supported terminals (#185541)
In #162162, I added support for OSC 9;4 graphical progress. I put it
behind the `show-progress` setting because I didn't have a reliable way
to detect whether the escape code was supported by the terminal.

Since then, more tools have added support for it, most notably Claude
Code and Homebrew. While I still don't have a good way to detect this,
there are a handful of known terminals that are easy enough to identify.

This PR toggles the default of `show-progress` to on again and puts
showing the progress behind a check for those known terminals (Windows
Terminal, ConEmu & Ghostty).

This means that if you're running in one of those, you'll get the visual
progress by default unless you set `show-progress` to off. The downside
is that if you're on an unrecognized terminal, you can't force it on any
longer by setting `show-progress` to on. I think that's a fair trade-off
as the setting wasn't really advertised and I doubt many people are
using that. As a workaround, they can set `OSC_PROGRESS` to spoof an
OSC-supporting terminal.
2026-03-12 14:36:36 -07:00
Michael Buch f58cffb273 [lldb][Debugger] Register 'testing.XXX' settings with Debugger (#185897)
The `testing.XXX` settings (added in
https://github.com/llvm/llvm-project/pull/177279 and currently just
`testing.inject-variable-location-error`) are supposed to only exist in
asserts builds. However, we never added it as a global property to the
`Debugger`, so the setting wasn't actually usable, in any build.

The one test that did use it [skipped the test on
error](https://github.com/llvm/llvm-project/blob/230e4656170e3764db28b54d91153a1117290171/lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py#L286-L288)
as a way to mimick "only run test in asserts mode". However, this just
meant the test never ran.

This patch registers the property and adds a test that ensures an
asserts-LLDB does allow access to it from the CLI.
2026-03-11 15:37:07 +00:00
Jonas Devlieghere 28638f5197 [lldb] Remove Debugger::{FindTargetWithProcessID, FindTargetWithProcess} (#184446)
In #184259, Jim noticed that Debugger::FindTargetWithProcess and
Debugger::FindTargetWithProcessID are rather poorly designed APIs as
tehy allow code running in one Debugger to mess with Targets from
another Debugger. The only use is Process::SetProcessExitStatus which
isn't actually used.
2026-03-03 14:29:15 -08:00
Jonas Devlieghere 6b5c55ef16 [lldb] Fix 10 year old leak of g_debugger_list_ptr (#184259)
Roughly 10 years ago, in aacb80853a, Greg
deleted the call to delete g_debugger_list_ptr because of a race
condition:

> Fixed a threading race condition where we could crash after calling
Debugger::Terminate().
> 
> The issue was we have two global variables: one that contains a
DebuggerList pointer and one that contains a std::mutex > pointer. These
get initialized in Debugger::Initialize(), and everywhere that uses
these does:
> 
> if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
> {
> std::lock_guard<std::recursive_mutex>
guard(*g_debugger_list_mutex_ptr);
>     // do work while mutex is locked
> }
> 
> Debugger::Terminate() was deleting and nulling out g_debugger_list_ptr
which meant we had a race condition where someone might do the if
statement and it evaluates to true, then another thread calls
Debugger::Terminate() and deletes and nulls out g_debugger_list_ptr
while holding the mutex, and another thread then locks the mutex and
tries to use g_debugger_list_ptr. The fix is to just not delete and null
out the g_debugger_list_ptr variable.

However, this isn't necessary as long as we persist ("leak") the mutex
and always check it first. That's exactly what this patch does. Without
it, the assert in Debugger::Initialize is incorrect.

```
assert(g_debugger_list_ptr == nullptr &&
       "Debugger::Initialize called more than once!");
```
2026-03-03 13:15:49 -08:00
Alex Langford 3490d28c8c [lldb] Remove last references to fbsdvm (#183418)
Support was removed in #181283
(a8cd1ac705)
2026-02-26 10:48:21 -08:00
Charles Zablit 5d5301dc0c [lldb] add a marker around hidden frames (#181143)
This is a reland of https://github.com/llvm/llvm-project/pull/167550.
Instead of relying on libcpp for testing, we emulate our own hidden
frames. This was originally causing tests failures on Windows.
2026-02-16 15:49:34 +01:00
Nerixyz cdbe28887b [LLDB] Set and verify paths of properties from tablegen (#179524)
In #168245, I attempted to dump the available settings to Markdown. That
required a full build of LLDB. However, to build the docs, only the swig
wrappers should need to be compiled. The comment was that we should be
able to use the definitions from the TableGen files.

Currently, the property definitions in don't have information about the
path where they will be available. They only contain a `Definition`
which groups properties, so they can be added to
`OptionValueProperties`.

With this PR, I'm adding the path for each property definition. For
example, `symbols.enable-external-lookup` would have `Name =
enable-external-lookup, Path = symbols`. In LLDB itself, we don't need
this path, we only need it for the documentation. To avoid mismatches
between the actual path and the declared one, I added a debug-only check
when a property group is added to a parent
(`OptionValueProperties::AppendProperty`).

The TableGen emitter for the properties now additionally emits
`g_{definition}_properties_def`, which includes both the array of
properties and the expected path. This constant has to be used to
initialize a `OptionValueProperties`.

I couldn't test this for everything (e.g. IntelPT or ProcessKDP), but
the necessary changes are simple: (1) set the `Path` in the TableGen
file, (2) update `initialize` to use `_def`.
2026-02-10 19:43:29 +01:00
Adrian Prantl a24f6ce743 [LLDB] Add a setting to simulate variables with missing locations (#177279)
Writing testcases for error handling that depends on specific DWARF is
very difficult and the resulting tests tend not to be very portable.
This patch adds a new setting to inject an error into variable
materialization, thus making it possible to write very simple source
code based tests for error handling instead.

This is primarily motivated by the Swift language plugin, but
functionality is generic and should be useful for other languages as
well.
2026-01-22 16:44:27 -08:00
Charles Zablit 09b45640a7 Revert "[lldb] add a marker before hidden frames (#167550)" (#176747) 2026-01-19 13:14:50 +00:00
Charles Zablit e43331f94a [lldb] add a marker before hidden frames (#167550)
**This patch adds a marker to make hidden frames more explicit.**

---

Hidden frames can be confusing for some users, who see that the indexes
of the frames in a backtrace are not contiguous. This patch aims to
lessen the confusion by adding a delimiter for the first and last non
hidden frame, i.e the boundaries.

IDE's like Xcode and VSCode represent those in the UI by having the
hidden frames either greyed out or collapsed.

It's not possible to do this in the CLI, therefore, this patch makes use
of 2 unicode characters to mark the beginning and end of the hidden
frames range.

This patch depends on:
- https://github.com/llvm/llvm-project/pull/168603

# Examples

In the example below, frame `#2` to `#7` are is hidden, and therefore,
frame `#1` is the first non hidden frame of the range while frame `#8`
is the last non hidden frame:
<img width="488" height="112" alt="Screenshot 2025-11-18 at 18 41 11"
src="https://github.com/user-attachments/assets/a21431da-9729-4cf0-a6bc-024aa306fc45"
/>

If the selected frame is one of the 2 boundary frames, we replace the
delimiter character with the select character (`*`).

<img width="487" height="111" alt="Screenshot 2025-11-18 at 18 41 03"
src="https://github.com/user-attachments/assets/5616fa81-6db6-457d-9d1e-bbe46e710c26"
/>
<img width="488" height="111" alt="Screenshot 2025-11-18 at 18 40 55"
src="https://github.com/user-attachments/assets/93dfa6cf-0956-4718-b31c-f965ec72b56d"
/>
2026-01-19 11:43:45 +01:00
Michael Buch 8f1cd07e3f [lldb][Format] Introduce a FormatEntity::Formatter class and move the Format API into it (#174618)
This patch creates a new `FormatEntity::Formatter` class and moves
`FormatEntity::Format` (and related APIs) into it. Most of the
parameters to `Format` are immutable across all recursive calls, so I
made them `const` member variables of `Formatter`. The main changes are
just mechanical renaming of:
```
FormatEntity::Format(...)
```
to
```
FormatEntity::Formatter(...).Format(stream, entry, valobj)
```
and making use of the member variables from inside `Format`.

We can probably make most of the parameters to the `Formatter`
constructor defaulted, but I chose not to in this patch to keep the diff
smaller.

The motivation for this is that I'm planning on adding logic to detect
recursive format entities (which would crash LLDB). That requires some
state, which in my opinion is best kept inside the `Formatter` class
instead of another parameter to `Format`.

The patch should be entirely NFC.
2026-01-07 15:40:55 +00:00
David Spickett 38657c0ded [lldb] Add zlib to version -v output (#174753)
I know this is required for at least one feature, because
TestSectionAPI.py has failures if zlib isn't enabled. So I think it's
useful for users to be able to check.

Now that it's in the config, I have also used it to make a test
annotation so we don't get the failure in TestSectionAPI.py when zlib is
disabled.

Which for future reference was:
Traceback (most recent call last):
File
"/home/davspi01/llvm-project/lldb/packages/Python/lldbsuite/test/decorators.py",
line 452, in wrapper
    return func(self, *args, **kwargs)
File
"/home/davspi01/llvm-project/lldb/test/API/python_api/section/TestSectionAPI.py",
line 67, in test_compressed_section_data
self.assertEqual(section_data, [0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
0x80, 0x90])
AssertionError: Lists differ: [] != [32, 48, 64, 80, 96, 112, 128, 144]

As it failed to decode the compressed section.
2026-01-07 15:26:55 +00:00
Jonas Devlieghere bc9f96a5e6 [lldb] Dump build configuration with version -v (#170772)
Add a verbose option to the version command and include the "build
configuration" in the command output. This allows users to quickly
identify if their version of LLDB was built with support for
xml/curl/python/lua etc. This data is already available through the SB
API using SBDebugger::GetBuildConfiguration, but this makes it more
discoverable.

```
(lldb) version -v
lldb version 22.0.0git (git@github.com:llvm/llvm-project.git revision 21a2aac5e5456f9181384406f3b3fcad621a7076)
  clang revision 21a2aac5e5456f9181384406f3b3fcad621a7076
  llvm revision 21a2aac5e5456f9181384406f3b3fcad621a7076
  editline_wchar: yes
  lzma: yes
  curses: yes
  editline: yes
  fbsdvmcore: yes
  xml: yes
  lua: yes
  python: yes
  targets: [AArch64, AMDGPU, ARM, AVR, BPF, Hexagon, Lanai, LoongArch, Mips, MSP430, NVPTX, PowerPC, RISCV, Sparc, SPIRV, SystemZ, VE, WebAssembly, X86, XCore]
  curl: yes
```

Resolves #170727
2025-12-08 10:11:39 -08:00
John Harrison bb9df2e3bd [lldb] Ensure FILE* access mode is correctly specified when creating a NativeFile. (#167764)
If we open a `NativeFile` with a `FILE*`, the OpenOptions default to
`eOpenOptionReadOnly`. This is an issue in python scripts if you try to
write to one of the files like `print("Hi",
file=lldb.debugger.GetOutputFileHandle())`.

To address this, we need to specify the access mode whenever we create a
`NativeFile` from a `FILE*`. I also added an assert on the `NativeFile`
that validates the file is opened with the correct access mode and
updated `NativeFile::Read` and `NativeFile::Write` to check the access
mode.

Before these changes:
```
$ lldb -b -O 'script lldb.debugger.GetOutputFileHandle().write("abc")'
(lldb) script lldb.debugger.GetOutputFileHandle().write("abc")
Traceback (most recent call last):
  File "<input>", line 1, in <module>
io.UnsupportedOperation: not writable
```

After:
```
$ lldb -b -O 'script lldb.debugger.GetOutputFileHandle().write("abc")'
(lldb) script lldb.debugger.GetOutputFileHandle().write("abc")
abc3
```

Fixes #122387
2025-11-17 10:51:13 -08:00
Jonas Devlieghere 578c03f7e5 [lldb] Support OSC escape codes for native progress (#162162)
This PR adds support for emitting the OSC `9;4` sequences to show a GUI
native progress bar.

There's a limited number of terminal emulators that support this, so for
now this requires explicit opt-in through a setting. I'm reusing the
existing `show-progress` setting, which became a NOOP with the
introduction of the statusline. The option now defaults to off.

Implements #160369
2025-10-13 13:48:41 -07:00
Jonas Devlieghere d136fbdf8c [lldb] Rework how we pass the execution context to the statusline (#159887)
Currently, we always pass the "selected" execution context to the
statusline. When handling a process or thread event, we can be more
precise, and build an execution context from the event data. This PR
also adopts the new `StoppedExecutionContext` that was recently
introduced.
2025-09-23 14:18:11 -07:00
Jonas Devlieghere 1eb795413d [lldb] Correctly restore the cursor column after resizing the statusline (#146132)
This PR ensures we correctly restore the cursor column after resizing
the statusline. To ensure we have space for the statusline, we have to
emit a newline to move up everything on screen. The newline causes the
cursor to move to the start of the next line, which needs to be undone.

Normally, we would use escape codes to save & restore the cursor
position, but that doesn't work here, as the cursor position may have
(purposely) changed. Instead, we move the cursor up one line using an
escape code, but we weren't restoring the column.

Interestingly, Editline was able to recover from this issue through the
LineInfo struct which contains the buffer and the cursor location, which
allows us to compute the column. This PR addresses the bug by having
Editline "refresh" the cursor position.

Fixes #134064
2025-06-30 14:34:35 -07:00
Jonas Devlieghere e8abdfc88f [lldb] Make MCP server instance global (#145616)
Rather than having one MCP server per debugger, make the MCP server
global and pass a debugger id along with tool invocations that require
one. This PR also adds a second tool to list the available debuggers
with their targets so the model can decide which debugger instance to
use.
2025-06-25 13:46:33 -07:00
Jonas Devlieghere 9524bfb270 [lldb] Add Model Context Protocol (MCP) support to LLDB (#143628)
This PR adds an MCP (Model Context Protocol ) server to LLDB. For
motivation and background, please refer to the corresponding RFC:
https://discourse.llvm.org/t/rfc-adding-mcp-support-to-lldb/86798

I implemented this as a new kind of plugin. The idea is that we could
support multiple protocol servers (e.g. if we want to support DAP from
within LLDB). This also introduces a corresponding top-level command
(`protocol-server`) with two subcommands to `start` and `stop` the
server.

```
(lldb) protocol-server start MCP tcp://localhost:1234
MCP server started with connection listeners: connection://[::1]:1234, connection://[127.0.0.1]:1234
```

The MCP sever supports one tool (`lldb_command`) which executes a
command, but can easily be extended with more commands.
2025-06-20 10:48:04 -05:00
Chelsea Cassanova a630ca6f6c [lldb][breakpoint] Grey out disabled breakpoints (#91404)
This commit adds colour settings to the list of breakpoints in order to
grey out breakpoints that have been disabled.
2025-06-18 13:06:20 -07:00
Jonas Devlieghere 6760857bf3 [lldb] Fix data race in statusline format handling (#142489)
This fixes a data race between the main thread and the default event
handler thread. The statusline format option value was protected by a
mutex, but it was returned as a pointer, allowing one thread to access
it while another was modifying it.

Avoid the data race by returning format values by value instead of by
pointer.
2025-06-03 19:12:30 -07:00
Kazu Hirata ef29a79adf [lldb] Use llvm::find_if (NFC) (#141385) 2025-05-25 08:21:30 -07:00
David Spickett 09488bcfba [lldb] Disable statusline on Windows (#138111)
Something to do with control code handling in Windows terminals breaks
the statusline in various ways. It makes LLDB unusable and even if you
set the setting to disable statusline, it's too late, and the terminal
session is now in a weird state.

See https://github.com/llvm/llvm-project/issues/134846 for more details.

Until we figure this out, don't allow it to be used on Windows.
2025-05-01 16:40:47 +01:00
Vy NguyenandPavel Labath a74e4ac9d5 [LLDB][Telemetry] Collect telemetry from client when allowed. (#129728)
This patch is slightly different from other impl in that we dispatch
client-telemetry via a different helper method. This is to make it
easier for vendor to opt-out (simply by overriding the method to do
nothing). There is also a configuration option to disallow collecting
client telemetry.

---------

Co-authored-by: Pavel Labath <pavel@labath.sk>
2025-04-26 02:19:29 +02:00
Ely Ronnen 290ba281e8 [lldb-dap] Show assembly depending on stop-disassembly-display settings (#136494)
Show assembly code when the source code for a frame is not available in
the debugger machine

Edit: this functionality will work only when using
`stop-disassembly-display = no-source` in the settings

Fix #136492

After the fix:

[Screencast From 2025-04-20
18-00-30.webm](https://github.com/user-attachments/assets/1ce41715-cf4f-42a1-8f5c-6196b9d685dc)
2025-04-25 14:35:20 -07:00
Jonas Devlieghere 3ccfbc8a00 [lldb] Make sure changing the separator takes immediate effect (#136779)
The setter is only used when changing the setting programmatically. When
using the settings command, we need to monitor SetPropertyValue.
2025-04-22 22:38:28 -07:00
Adrian Prantl 6f1adbdb2b [lldb] Make the statusline separator configurable (#136611)
And use this functionality to replace the ASCII "|" with the same
full-geight line-drawing character used in diagnostics rendering on a
color terminal.
2025-04-22 12:59:46 -07:00
Ebuka EzikeandJonas Devlieghere d7d1706564 [lldb] Fix use-color settings not persistent (#135626)
Fixes https://github.com/llvm/llvm-project/issues/22981

If `settings set use-color` is changed when lldb is running it does not take effect. 
This is fixes that.

---------

Signed-off-by: Ebuka Ezike <yerimyah1@gmail.com>
Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
2025-04-22 12:21:23 +01:00
Pavel Labath f4fba20726 [lldb] Remove vestigial remnants of reproducers (#135361)
Not touching the SB API.
2025-04-13 08:55:24 +02:00
Jonas Devlieghere 70627af91f [lldb] Synchronize access to m_statusline in the Debugger (#134759)
Eliminate the potential for a race between the main thread, the default
event handler thread and the signal handling thread, when accessing the
m_statusline member.
2025-04-11 08:53:49 -07:00
Jonas Devlieghere a62b9b387f [lldb] Calling Debugger::SetStatuslineFormat should redraw the statusline 2025-04-10 16:55:59 -07:00
Jonas Devlieghere 2b984fd0e3 [lldb] Support programmatically setting the statusline format (NFC) (#135250)
Support programmatically setting the statusline format. I want to use
this API downstream, to change the statusline format for the Swift REPL.
2025-04-10 15:36:28 -07:00