3087 Commits

Author SHA1 Message Date
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
Felipe de Azevedo Piovezan
4df296733d
[lldb] Implement llvm::formatv overload for Stream::operator << (#187462)
This will allow us to more conveniently use llvm::formatv in the
codebase.
2026-03-20 08:08:48 +00:00
Jason Molenda
fb36a54ef6
[lldb] Rename formatv verbose log call, misc log cleanups [NFC] (#186951)
lldb had three preprocessor defines for logging,

LLDB_LOG  - formatv style argument
LLDB_LOGF - printf style argument
LLDB_LOGV - formatv style argument, only when verbose enabled

If you weren't looking at Log.h and the definition of these three, and
wanted to log something with formatv, it was easy to use LLDB_LOGV by
accident. We just had a situation where an important log statement
wasn't logging and it turned out to be this. This is fragile if you
aren't looking at the header directly, so I'd like to make this more
explicit. My proposal:

LLDB_LOG  - formatv style argument
LLDB_LOG_VERBOSE - formatv style argument, only when verbose enabled 
LLDB_LOGF - printf style argument
LLDB_LOGF_VERBOSE - printf style argument, only when verbose enabled

The new fouth one is to remove several places where we do `if (log &&
log->GetVerbose()) LLDB_LOGF (...)` in the sources today, and make both
styles consistent.

This PR implements that change, mechanically changing all LLDB_LOGV's to
LLDB_LOG_VERBOSE.

It also updates many of the `if (log && log->GetVerbose()) LLDB_LOGF`'s.
Some uses of this conditional expression do extra calculations in
addition to logging, and so those were left as-is so we're not doing
throwaway work when running without verbose logging.

There were many instances throughout lldb where callers are still doing
`if (log) LLDB_LOG*(...)`, a remnant of when all calls were to the `Log`
object's `Printf()` method, and you had to check if your local Log*
pointer was non-nullptr before calling the method. I removed those,
again keeping ones where work for logging is done in the block of code.

The code changes are all mechanical and uninteresting, but the question
of whether this naming change is widely agreed on is maybe worth
discussing.
2026-03-18 16:31:33 -07:00
Steven Wu
480eba33e2
[lldb][PrefixMap] follow up fixes to #187145 (#187337)
Fix and improve #187145 for following issues:
* Fix unhandled error.
* Align the log type with the file where it contains.
* The added test doesn't work on windows host for remote debugging, add
  decorator to skip when host and target do not match.
2026-03-18 11:32:41 -07:00
Steven Wu
1b8db068ed
[PrefixMap] Teach lldb to auto-load compilation-prefix-map.json (#187145)
Add a LoadCompilationPrefixMap() helper in SymbolFile::FindPlugin that
walks up from the symbol file's directory looking for a
compilation-prefix-map.json file. When found, each key→value entry is
applied to the module's source path mapping list, allowing LLDB to
resolve source file paths that were rewritten by -fdebug-prefix-map at
build time without requiring manual `settings set target.source-map`.

The JSON file format maps fake paths (as written into debug info) back
to their real on-disk counterparts:
  { "/fake/srcdir": "/real/srcdir" }

Directory results are cached so the filesystem is walked at most once
per unique directory across all modules loaded in a session.

Also apply the module's source path remappings in
SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex when constructing
compile units from N_SO stabs. This mirrors what MakeAbsoluteAndRemap
does for the dSYM case so that fake paths baked into the debug map are
transparently resolved to real paths.

rdar://84824567

Assisted-By: Claude
2026-03-18 09:11:28 -07:00
Michael Buch
d9eba8b355
[lldb][Module] Don't try to locate scripting resources without a ScriptInterpreter (#187091)
I'm in the process of moving `SanitizedScriptingModuleName` into
`ScriptInterpreter` as a `virtual` API. The nullptr check inside the
constructor made that more difficult because it implied we may not have
a `ScriptInterpreter` available to call the sanitization API on. Really
the `nullptr` check is redundant because even if we succesfully sanitize
and then locate some scripts, `Module::LoadScriptingResourceInTarget`
bails out if we don't have a `ScriptInterpreter`.

This patch moves the early exit in `LoadScriptingResourceInTarget` to
before we make the call to `LocateExecutableScriptingResources`. That
way we ensure we never get to `SanitizedScriptingModuleName` without a
valid `ScriptInterpreter`.
2026-03-18 00:09:15 +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
Michael Buch
adb04f86f8
[lldb][Module][NFC] Use raw string literal and formatv-style format in LoadScriptingResourceInTarget (#186411)
Makes it obvious what the warning will look like (with the indenentation
etc.). Also adds a test since we had no coverage for the warning before
(as far as I'm aware).
2026-03-13 15:13:35 +00:00
Michael Buch
b3bc1f543f
[lldb][Module][NFC] Use early-return style in LoadScriptingResourceInTarget (#186392)
Planning on adding more to this function/loop soon. Making it
early-return style (as suggested by the LLVM style guide) makes those
changes easier to reason about.

Drive-by:
* Reduced the indentation of the loop by doing an early-continue if the
`FileSpec` is invalid or doesn't exist
2026-03-13 14:39:13 +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
Jonas Devlieghere
bf2e4585d2
[lldb] Reinstate ~PluginInstances assertion (#185537)
This re-enables the assertion in the PluginInstances destructor that
catches plugins that were not unregistered in their Terminate method. It
also adds a helpful message to quickly identify the plugin.
2026-03-11 13:36:49 -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](230e465617/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
9062a02da6
[lldb] Temporarily remove the assert to unblock the bots (#185505)
The assert is triggering from Dexter in the cross-project-test. This
temporarily removes the assert while I address the issue.
2026-03-09 20:17:10 +00:00
Jonas Devlieghere
c182ca3e3a
[lldb] Assert & fix missing calls to UnregisterPlugin (#185162)
Fix missing calls to UnregisterPlugin and add an assert in the
PluginManager that ensures all plugins have been unregistered by the
time the plugin manager is destroyed.
2026-03-09 13:04:08 -07:00
Jonas Devlieghere
32c51ee254
[lldb] Implement PluginInfo move constructor (#185137)
The default move constructor wasn't nulling out the callbacks. Combined
with the fact that llvm::sys::DynamicLibrary has no explicit move
constructor and hence library.isValid() still returned true after having
moved-from, we would end up calling plugin_term_callback() when
destroying the moved-from PluginInfo, calling it prematurely.
2026-03-07 00:02:23 +00:00
Jonas Devlieghere
541d546c2e
[lldb] Use llvm::SmallVector in the PluginManager (NFC) (#184912)
Most of the plugins have only a small number of instances. Use
`llvm::SmallVector` instead of `std::vector`.

Depends on https://github.com/llvm/llvm-project/pull/184837
2026-03-06 15:46:16 -08:00
Jonas Devlieghere
81a537e708
[lldb] Use range-based for loops over plugins (#184837)
This PR replaces the Get*CallbackAtIndex pattern in the PluginManager
with returning a snapshot of callbacks that the caller can iterate over
using a range-based for loop. This is a continuation of #184452 which
added thread safety by using snapshots. However, that introduced a bunch
of unnecessary copies which are largely eliminated again by getting the
snapshot once when gather all the callbacks, rather than doing that on
each iteration when querying a plugin for a given index. It also
eliminates the possibility of the snapshot changing underneath you when
iterating over the plugins.

This change was largely mechanical and I used Claude to do the menial
work of updating the signatures and call sites.
2026-03-06 22:48:33 +00:00
Jonas Devlieghere
64c0f624cd
[lldb] Make the PluginManager thread safe (#184452)
In #184273, John pointed out that the PluginManager is currently not
thread safe. While we don't currently provide any guarantees, it seems
desirable to be able to interact safely with the PluginManager from
different threads. For example, we allow dynamically loading plugins
from the command interpreter, which in theory could be coming from
different threads.
2026-03-04 10:06:19 -08: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 aacb80853a46bd544fa76a945667302be1de706c, 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
(a8cd1ac7058efdf7a9be823182da884243ca6c0b)
2026-02-26 10:48:21 -08:00
Jason Molenda
3f024d0835
[lldb] A few small code modernizations and cleanups [NFC] (#182656)
I was reading through ObjectContainerBSDArchive and came across some
dead method decls, a less-than-completely-clear `shared_ptr` typedef in
`ObjectContainerBSDArchive::Archive` for a shared_ptr<Archive> which was
a little unclear when reading a decl like `shared_ptr archive_sp;` for a
local variable.
2026-02-23 22:03:40 -08:00
Augusto Noronha
b3f3b57aed
[lldb] Speed up SymbolContextList::AppendIfUnique (#181952)
d7fb086668dff68 changed some calls from SymbolContextList::Append to
SymbolContextList::AppendIfUnique. This has unfortunately caused a huge
slow down in operations involving a large amount of symbol contexts (for
example, trying to autocomplete from an empty input "b <TAB>" will add
every function to the list), since AppendIfUnique scans the entire
symbol context list. Speed this up by adding a hash set to quickly
answer whether a symbol context is on the list or not.

This takes the time from running "b <TAB>" when debugging yaml2obj on my
machine from 600 seconds down to 13, which is about the same as before
d7fb086668dff68.

Note that AppendIfUnique has a logic error, which has been present since
its introduction. This has to do with the behavior controlled by
"merge_symbol_into_function", which will try to merge symbols with
symbol context containing the equivalent function to that symbol.

The previous patch tried to correct this by adding
CompareConsideringPossiblyNullSymbol(), which is not quite correct.

With CompareConsideringPossiblyNullSymbol(), if symbols are added in
this order:

- Symbol context without symbol.
- Equivalent symbol context with symbol.

The list will have only one symbol context WITHOUT the symbol.

If we stop using CompareConsideringPossiblyNullSymbol() and instead go
back to the == operator which d7fb086668dff68 introduced, with symbols
added in this order, the following will happen:

- Symbol context without symbol.
- Equivalent symbol context with symbol.
- The bare symbol, with "merge_symbol_into_function = true", the list
will have the same symbol twice.

This patch does not attempt to solve this, and instead focuses on the
performance issue d7fb086668dff68 introduced.

rdar://170477680
2026-02-23 11:41:13 -08:00
Charles Zablit
796a1ea79f
[lldb][windows] fix a race condition when closing the ConPTY (#182302)
This patch fixes a race condition when closing the ConPTY of a process
on Windows.

The read operation in `ConnectionGenericFile::Read` is asynchronous
because the ConPTY does not work with synchronous reads. However, this
is prone to a race condition if the ConPTY is closed between the
`ReadFile` and the `WaitForMultipleObjects`. This eventually leads to
the data being truncated, i.e some of the STDOUT is missing.

The fix is to introduce a mutex which prevents the ConPTY from closing
while a Read loop is in progress.

At the end of the pipe, `WaitForMultipleObjects` hangs until it receives
a `ERROR_BROKEN_PIPE` event, which is signaled when closing the ConPTY.
It's important to close the Read thread before closing the ConPTY,
otherwise the thread deadlocks waiting for the `ERROR_BROKEN_PIPE` which
is never sent because the ConPTY is waiting for the thread to exit
before closing.

All of this logic is encapsulated in the `ConnectionConPTY` class which
is a subclass of `ConnectionGenericFile`. `ConnectionConPTY` only
supports reading from the ConPTY. To write to it,
`IOHandlerProcessSTDIOWindows` should be used instead.

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

This patch replaces https://github.com/llvm/llvm-project/pull/182109.

---------

Co-authored-by: Nerixyz <nero.9@hotmail.de>
2026-02-23 17:21:06 +00:00
Jonas Devlieghere
a14b72ba63
[lldb] Automatically discover and load dynamic LLDB Plugins (#182628)
LLDB's architecture is heavily centered around plugins. Its primary
purpose is abstraction and modularity, more so than extensibility. For
example, all the in-tree plugins are linked in statically. However, it
is possible to load modules dynamically, though that's mostly aimed at
plugins that built on top of the stable public SB API.

I'm working on support for loading modules dynamically, specifically
in-tree modules that use the LLDB_PLUGIN_DEFINE macro and the
corresponding CMake machinery.

This PR adds support for initializing modules using the symbols
generated by the aforementioned macro. This makes it possible to convert
plugins to shared libraries with minimal changes: is:

 - Replace PLUGIN with SHARED in the plugin's CMakeLists.txt.
- Link against libLLDB instead of linking statically against LLVM and
LLDB libraries.
- Re-export all private symbols from libLLDB with
`-DLLDB_EXPORT_ALL_SYMBOLS=ON`.
2026-02-23 08:59:44 -08:00
Jonas Devlieghere
11af80c3ec
[lldb] Go through the plugin interface to obtain the scripting path (#182400)
Avoid directly including `ScriptInterpreterPython.h` in `SBHostOS`, and
instead go through the plugin interface to obtain the scripting path.
This also deprecates the ``SBHostOS::GetLLDBPythonPath`` method in favor
of the more generic GetScriptPath variant.
2026-02-19 16:41:00 -08:00
Sergei Barannikov
b881949ee4
[lldb] Drop incomplete non-8-bit bytes support (#182025)
This was originally introduced to support kalimba DSPs featuring 24-bit
bytes by f03e6d84 and also c928de3e, but the kalimba support was mostly
removed by f8819bd5. This change removes the rest of the support, which
was far from complete.
2026-02-19 13:01:02 +03:00
Jonas Devlieghere
091296f3e3
[lldb] Revert scripted symbol locator (#181945)
This revert #181334 and its follow-up PRs (including #181488, #181492,
#181493, #181494 and #181498) as well as Ismail's documentation changes
(#181594, #181717). The original commit causes a test failure in CI
(https://github.com/llvm/llvm-project/issues/181938) but the more I look
at the patch, the more I'm convinced it was not ready to land. It will
be easier to iterate on the feedback by re-landing this than by using
post-commit review.
2026-02-17 16:52:21 -08:00
Charles Zablit
3bfe821621
[lldb][windows] handle ERROR_INVALID_HANDLE error (#181809)
On Windows, `ThreadedCommunication::ReadThread` can fail with
`ERROR_INVALID_HANDLE` when the ConPTY is closed. Currently it's not
caught, causing the `ReadThread` to continue forever because `done` is
never set to `true`. This causes an infinite hang.
2026-02-17 15:22:47 +00: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
rchamala
1ee03d1e09
[lldb] Add ScriptedSymbolLocator plugin for source file resolution (#181334)
## Summary                                                        
                                                                    
Based on discussion from
[RFC](https://discourse.llvm.org/t/rfc-python-callback-for-source-file-resolution/83545),
this PR adds a new `SymbolLocatorScripted` plugin that allows Python
scripts to implement custom symbol and source file resolution logic.
This enables downstream users to build custom symbol servers, source
file remapping, and build artifact resolution entirely in Python.
                                                                    
  ### Changes

- Adds `LocateSourceFile()` to the SymbolLocator plugin interface,
called during source path resolution with a fully loaded `ModuleSP`, so
the plugin has access to the module's UUID, file paths, and symbols.
- Adds `SymbolLocatorScripted` plugin that delegates all four
SymbolLocator methods (`LocateExecutableObjectFile`,
`LocateExecutableSymbolFile`, `DownloadObjectAndSymbolFile`,
`LocateSourceFile`) to a user-provided Python class.
- Adds `ScriptedSymbolLocatorPythonInterface` to bridge C++ calls to
Python, with proper GIL management and error handling.
- Results for `LocateSourceFile` are cached per (module UUID, source
file) pair.
- The Python class is configured via: `settings set
plugin.symbol-locator.scripted.script-class module.ClassName`

  ### Python class interface

  ```python
  class MyLocator:
      def __init__(self, exe_ctx, args): ...
      def locate_source_file(self, module, original_source_file):
  ...
      def locate_executable_object_file(self, module_spec): ...
      def locate_executable_symbol_file(self, module_spec,
  default_search_paths): ...
      def download_object_and_symbol_file(self, module_spec,
  force_lookup, copy_executable): ...
```

  ### Test plan
```
  Added TestScriptedSymbolLocator.py with 3 test cases:
  - test_locate_source_file — verifies the locator resolves source
  files, receives a valid SBModule with UUID, and remaps paths correctly
  - test_locate_source_file_none_fallthrough — verifies returning
None falls through to default LLDB resolution, and that having no script
  class set works normally
  - test_invalid_script_class — verifies graceful handling of
  invalid class names without crashing
```

Co-authored-by: Rahul Reddy Chamala <rachamal@fb.com>
2026-02-14 07:39:00 -08:00
Jason Molenda
d406ce8e20
[lldb][macOS] Don't fetch settings in Host, to keep layering (#181406)
I introduced a dependency from Host on Core without realizing it in an
earlier PR, while adding a setting to disable the new shared cache
binary blob scanning/reading in HostInfoMacOSX, which caused build
problems. Thanks to Alex for figuring out the build failure I caused.

Add a bool to the methods in HostInfoMacOSX, and have the callers (in
Core and various plugins etc) all fetch the
symbols.shared-cache-binary-loading setting from ModuleList, and pass
the result in.

The least obvious part of this is in ProcessGDBRemote where we first
learn the shared cache filepath & uuid, it calls
HostInfoMacOSX::SharedCacheIndexFiles() - this is only called when the
shared cache binary loading is enabled, so I conditionalize the call to
this method based on the setting.

rdar://148939795
2026-02-13 16:31:05 -08:00
Jonas Devlieghere
8c162b70ac
[lldb] Pass the frame's language type to the highlighter (#181094)
This threads the frame's language type through the source manager to the
highlighter. Previously, we'd always pass "unknown" as the language type
and rely on the language plugin to figure out the language based on the
file extension.

This change is motivated by #170250. For languages like Swift or Rust
that don't have an upstream language plugin, we need the frame's
language for syntax highlighting.
2026-02-13 08:41:17 -08:00
Jonas Devlieghere
5e2518f2cc
[lldb] Convert highlighters to plugins (#181026)
This PR converts the syntax highlighters to plugins. Previously, the
highlighters were part of the Language plugin, using a library shared by
the C-like languages. The Highlighters already had a plugin-like design,
with a clang and default highlighter. This PR takes them out of the
language plugin and into their own highlighter plugin. They are still
accessed thought he HighlightManager.

This change is motivated by #170250. It will allow us to have both a
clang and tree-sitter based highlighter, as well as make it possible to
have a highlighter for a language that doesn't have an upstream language
plugin, like Swift or Rust.
2026-02-12 09:09:47 -08: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
Jason Molenda
e3c72cf008
[lldb] Add a new way of loading files from a shared cache (#179881)
Taking advantage of a few new SPI in macOS 26.4 libdyld, it is possible
for lldb to load binaries out of a shared cache binary blob, instead of
needing discrete files on disk. lldb has had one special case where it
has done this for years -- if the debugee process and lldb itself are
using the same shared cache, it could create ObjectFiles based on its
own memory contents. This new method requires only the shared cache on
disk, not depending on it being mapped into lldb's address space
already.

In HostInfoMacOSX.mm, we create an array of binaries in lldb's shared
cache, by one of two methods depending on the availability of SPI/SDKs.
This PR adds a new third method for loading lldb's shared cache off disk
as a proof of concept. It will prefer this new method when the needed
SPI are available at runtime. There is also a user setting to disable
this new method in case we uncover a problem as it is deployed.

I did change the internal store of the shared cache files from a single
array, to being organized by shared cache UUIDs, so we can have multiple
shared caches indexed in the future.

In HostInfoBase.h's SharedCacheImageInfo class, you can now create an
ImageInfo with a DataExtractorSP or a void* baton. I added GetUUID and
GetExtractor methods, and the latter will use the libdyld SPI to map the
segments for a specific binary into lldb's memory and return a
DataExtractorSP.

The setting is currently called symbols.shared-cache-binary-loading.

In DynamicLoaderDarwin::FindTargetModuleForImageInfo there was an
ordering mistake where we would always consult the HostInfoMacOSX.mm
shared cache provider, instead of checking lldb's own global module
cache first when looking for a binary, resulting in creating a new
Module repeatedly for shared cache binaries with the new method, parsing
the symbol table repeatedly. I fixed the ordering so we look at existing
Modules before we check the shared cache for one.

In ObjectFileMachOTest, it tests a TEXT and a DATA symbol, checking that
the contents of the function/data object match the bytes we got from the
shared cache. The test was using a DATA_DIRTY symbol, which was fine
when using lldb's own shared cache memory, but when we worked on the
shared cache binary on-disk directly, we were seeing different values
for the bytes because of relocations in there. I changed this to a
constant DATA symbol.

rdar://148939795

---------

Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
Co-authored-by: Alex Langford <nirvashtzero@gmail.com>
2026-02-05 18:38:20 -08:00
Alex Langford
9ebdeb2e8c
[lldb] Return Expected<ModuleSP> from Process::ReadModuleFromMemory (#179583)
I noticed that Module::GetMemoryObjectFile populates a Status object
upon error but it's effectively dropped on the floor. Instead, the
clients can report the error as desired.

At the moment, all clients are either (1) consuming the error because
it's only trying to find a module, or (2) log the error and bail out
early. I tried to preserve existing behavior as faithfully as possible.
2026-02-05 11:49:17 -08:00
jimingham
fbb371affa
Prevents a potential lock inversion in StatusLine when shutting down. (#179789)
We have gotten reports of an occasional deadlock on shutdown. The
Driver::MainLoop thread is shutting down, and gets stuck here:

  Thread 0x3c017c
  start 
    main 
       Driver::MainLoop() 
         lldb::SBDebugger::RunCommandInterpreter(bool, bool) 

lldb_private::CommandInterpreter::RunCommandInterpreter(lldb_private::CommandInterpreterRunOptions&)
            lldb_private::Debugger::RunIOHandlers()

lldb_private::Debugger::PopIOHandler(std::__1::shared_ptr<lldb_private::IOHandler>
const&)
                 lldb_private::Editline::Cancel()
                   lldb_private::LockableStreamFile::Lock()
                     std::__1::recursive_mutex::lock()

It has acquired the IO Handler list lock (in PopIOHandler) and is stuck
trying to get the debugger output stream lock.

Meanwhile, the event-handler thread is doing:

  Thread 0x3c01d3
  thread_start
    _pthread_start
       lldb_private::HostThreadMacOSX::ThreadCreateTrampoline(void*) 
lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*)

std::__1::__function::__func<lldb_private::Debugger::StartEventHandlerThread()::$_0,
void* ()>::operator()()
            lldb_private::Debugger::DefaultEventHandler()
              lldb_private::Statusline::~Statusline()

lldb_private::Statusline::UpdateScrollWindow(lldb_private::Statusline::ScrollWindowMode)
                  lldb_private::Debugger::RefreshIOHandler() 
                    std::__1::recursive_mutex::lock()

UpdateScrollWindow gets the debugger output stream lock, and sends some
data to the output, then it calls RefreshIOHandler while still holding
the Debugger output stream lock. That's the problem, since if it gets
that lock before Editline::Cancel() completes, we'll get this deadlock.

The solution is simple, there's no reason why UpdateScrollWindow should
hold the debugger output lock when it calls RefreshIOHandler. If that
refresh ends up needing to write to the debugger output, it can take the
lock more narrowly at that point. This fixed the deadlock because after
yielding the output lock, the second thread waits on the first to get
the IO Handler lock. Meanwhile the first thread can now acquire the
debugger output lock and finish the Cancel, and exit PopIOHandler which
will allow the second thread to make progress in turn.

I couldn't figure out any way to test this...
2026-02-05 10:28:51 -08:00
Alex Langford
85c96ff3a0
[lldb][NFC] Remove unused method Module::SetUUID (#178803) 2026-02-02 10:22:20 -08:00
Ryan Mansfield
ec86761b63
[lldb] Fix typos in property descriptions. (#178757) 2026-01-30 13:27:26 +00:00
Jason Molenda
2aa020f49b
[lldb][NFC] Module, ModuleSpec, GetSectionData use DataExtractorSP (#178347)
In a PR last month I changed the ObjectFile CreateInstance etc methods
to accept an optional DataExtractorSP instead of a DataBufferSP, and
retain the extractor in a shared pointer internally in all of the
ObjectFile subclasses. This is laying the groundwork for using a
VirtualDataExtractor for some Mach-O binaries on macOS, where the
segments of the binary are out-of-order in actual memory, and we add a
lookup table to make it appear that the TEXT segment is at offset 0 in
the Extractor, etc. Working on the actual implementation, I realized we
were still using DataBufferSP's in ModuleSpec and Module, as well as in
ObjectFile::GetModuleSpecifications.

I originally was making a much larger NFC change where I had all
ObjectFile subclasses operating on DataExtractors throughout their
implementation, as well as in the DWARF parser. It was a very large
patchset. Many subclasses start with their DataExtractor, then create
smaller DataExtractors for parts of the binary image - the string table,
the symbol table, etc., for processing.

After consideration and discussion with Jonas, we agreed that a
segment/section of a binary will never require a lookup table to access
the bytes within it, so I changed
VirtualDataExtractor::GetSubsetExtractorSP to (1) require that the
Subset be contained within a single lookup table entry, and (2) return a
simple DataExtractor bounded on that byte range. By doing this, I was
able to remove all of my very-invasive changes to the ObjectFile
subclass internals; it's only when they are operating on the entire
binary image that care is needed.

One pattern that subclasses like ObjectFileBreakpad use is to take an
ArrayRef of the DataBuffer for a binary, then create a StringRef of
that, then look for strings in it. With a VirtualDataExtractor and
out-of-order binary segments, with gaps between them, this allows us to
search the entire buffer looking for a string, and segfault when it gets
to an unmapped region of the buffer. I added a
VirtualDataExtractor::GetSubsetExtractorSP(0) which gets the largest
contiguous memory region starting at offset 0 for this use case, and I
added a comment about what was being done there because I know it is not
obvious, and people not working on macOS wouldn't be familiar with the
requirement. (when we have a ModuleSpec with a DataExtractor, any of the
ObjectFile subclasses get a shot at Creating, so they all have to be
able to iterate on these)

rdar://148939795
2026-01-29 15:36:40 -08:00
n2h9
a617b901cd
[lldb] [disassembler] chore: add GetVariableAnnotations to SBInstruction api (#177676)
## Description
Contribution to this topic [Rich Disassembler for
LLDB](https://discourse.llvm.org/t/rich-disassembler-for-lldb/76952),
this part.
```
The rich disassembler output should be exposed as structured data and made available through LLDB’s scripting API so more tooling could be built on top of this
```

----

This pr replaces #174847

As was suggested in [this
comment](https://github.com/llvm/llvm-project/pull/174847#issuecomment-3757015552),
implement access to variable annotations from `SBInstruction` class
itself.

Notes:
-   did run black formatter on the python file;

## Testing
Run test with
```sh
./build/bin/lldb-dotest -v -p TestVariableAnnotationsDisassembler.py lldb/test/API/functionalities/disassembler-variables
```

all tests (9 existing + 1 newly added) are passing

<details>
<summary>screenshot 2026-01-23</summary>

build from the latest commit  08f00730b5768a8e3f7039d810084fabaaa24470

<img width="1506" height="562" alt="image"
src="https://github.com/user-attachments/assets/69516353-3432-47df-ae45-c40b51ec14c4"
/>

</details>

<details>
<summary>screenshot 2026-01-29</summary>

build from the latest commit  f48a1a2c10f96a457ca6844be2ccc9406d3d57a0

<img width="1232" height="740" alt="image"
src="https://github.com/user-attachments/assets/9d104ce6-36c3-430b-98fe-f028f83a6b6d"
/>


</details>

---------

Signed-off-by: Nikita B <n2h9z4@gmail.com>
2026-01-29 20:54:42 +01:00
Greg Clayton
5968e29dad
[lldb] Add the ability to load ELF core file executables and shared libraries from memory (#177289)
This patch enables ELF core files to be loaded and still show
executables and shared libraries. Functionality includes:
- Load executable and shared libraries from memory if ELF headers are
available
- Create placeholder for missing shared libraries and executable.
Previously you just wouldn't get anything in the "image list" if no
executable was provided.
2026-01-28 17:49:04 -08:00
Alex Langford
9ca02a13a4
[lldb][NFC] Mark Symbol pointers as const where easily possible (#177472)
These are the places that required no modifications to surrounding code.
2026-01-27 15:23:49 -08:00
Alex Langford
956485d39a
[lldb][NFC] Remove ObjectFile::ResolveSymbolForAddress (#177479)
Nothing overrides this method and the base class's implementation
returns nullptr.
2026-01-27 15:23:09 -08:00
GeorgeHuyubo
36acae1124
[lldb] Enable locate module callback for main executable in launch mode (#176266)
During target creation for launch mode, the locate module callback was
not invoked for the main executable because the Target doesn't exist yet
when ModuleList::GetSharedModule is called. This prevented custom module
location logic from being applied to the main executable.

This change adds a PlatformSP to ModuleSpec so that GetSharedModule can
call the locate module callback using the Platform directly, even when
Target is not available. The Platform is now set on the ModuleSpec in
TargetList::CreateTargetInternal before calling ResolveExecutable.

Co-authored-by: George Hu <georgehuyubo@gmail.com>
2026-01-27 13:28:53 -08: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
Michael Buch
f74c2668cc
[lldb][Module][NFC] Remove unused always_create parameter to GetSharedModule (#176325)
No caller sets this to `true`. Initially added for and set by
`SymbolFileDWARFDebugMap` (see
`616f490777a4f35269a23abee851680134050065`). This was then removed
shortly after in:
```
commit 762f7135e290696595b6c7233245581f59eeb07c
Author: Greg Clayton <gclayton@apple.com>
Date:   Sun Sep 18 18:59:15 2011 +0000

    Don't put modules for .o files into the global shared module list. We
    used to do this because we needed to find the shared pointer for a .o
    file when the .o file's module was needed in a SymbolContext since the
    module in a symbol context was a shared pointer. Now that we are using
    intrusive pointers we don't have this limitation anymore since any
    instrusive shared pointer can be made from a pointer to an object
    all on its own.
```

At this point it's more of a foot-gun, because forcing it to true has
potentially significant performance implications (e.g.,
a5eaa05dce)
2026-01-19 10:57:52 +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