3033 Commits

Author SHA1 Message Date
Med Ismail Bennani
6767b86c34
[lldb] Fix frame-format string missing space when module is invalid (#172767)
This patch is a follow-up to 96c733e to fix a missing space in the
frame.pc format entity. This space was intended to be prepended to the
module format entity scope but if the module is not valid, which is
often the case for python pc-less scripted frames, the space between the
pc and the function name is missing.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-12-18 13:38:58 +01:00
Augusto Noronha
208553460a
[lldb] Prefer exact address match when looking up symbol by address (#172055)
The current behavior will pick the first symbol that contains the
address, this causes LLDB to pick the wrong symbol when looking for
swift reflection metadata on Linux, as in that case it is valid for a
symbol to completely encompass another one.

Instead, this function should prefer the symbol which is an exact, if it
exists. As a bonus, this should also be faster in the vast majority of
the cases, as we probably query symbols by their exact address most of
the time.

rdar://166344740
2025-12-17 10:51:14 -08:00
Alex Langford
34f6303293
[lldb][NFCI] Make LookupInfo const (#171901)
Instead of changing an existing LookupInfo after creation, let's make
them constant.
2025-12-15 10:51:48 -08:00
Jason Molenda
e4c83b7b11
[lldb][NFC] Change ObjectFile argument type (#171574)
The ObjectFile plugin interface accepts an optional DataBufferSP
argument. If the caller has the contents of the binary, it can provide
this in that DataBufferSP. The ObjectFile subclasses in their
CreateInstance methods will fill in the DataBufferSP with the actual
binary contents if it is not set.
ObjectFile base class creates an ivar DataExtractor from the
DataBufferSP passed in.

My next patch will be a caller that creates a VirtualDataExtractor with
the binary data, and needs to pass that in to the ObjectFile plugin,
instead of the bag-of-bytes DataBufferSP. It builds on the previous
patch changing ObjectFile's ivar from DataExtractor to DataExtractorSP
so I could pass in a subclass in the shared ptr. And it will be using
the VirtualDataExtractor that Jonas added in
https://github.com/llvm/llvm-project/pull/168802

No behavior is changed by the patch; we're simply moving the creation of
the DataExtractor to the caller, instead of a DataBuffer that is
immediately used to set up the ObjectFile DataExtractor. The patch is a
bit complicated because all of the ObjectFile subclasses have to
initialize their DataExtractor to pass in to the base class.

I ran the testsuite on macOS and on AArch64 Ubutnu. (btw David, I ran it
under qemu on my M4 mac with SME-no-SVE again, Ubuntu 25.10, checked
lshw(1) cpu capabilities, and qemu doesn't seem to be virtualizing the
SME, that explains why the testsuite passes)

rdar://148939795

---------

Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
2025-12-11 10:08:56 -08:00
Michael Buch
1b7f272906
[lldb][Module] Only log SDK search error once per debugger session (#171820)
Currently if we are debugging an app that was compiled against an SDK
that we don't know about on the host, then every time we evaluate an
expression we get following spam on the console:
```
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
error: Error while searching for Xcode SDK: Unrecognized SDK type: <some SDK>
```

It is not a fatal error but the way we spam it pretty much ruins the
debugging experience.

This patch makes it so we only log this error once per debugger session.

Not sure how to best test it since we'd need to build a program with a
particular SDK and then make it unrecognized by LLDB. Confirmed manually
that the error only gets reported once after this patch.
2025-12-11 17:25:45 +00:00
Jonas Devlieghere
c814ac1928
[lldb] Correct use_editline check in IOHandlerEditline (#171733)
Correct the use_editline check in IOHandlerEditline to prevent a crash
when we have an output and/or error file, but no stream. This fixes a
regression introduced by 58279d1 that results in a crash when calling
el_init with a NULL stream.

The original code was checking the stream: GetOutputFILE and
GetErrorFILE.

```
use_editline = GetInputFILE() && GetOutputFILE() && GetErrorFILE() &&
               m_input_sp && m_input_sp->GetIsRealTerminal();
```

The new code is checking the file: `m_output_sp` and `m_error_sp`.

```
use_editline = m_input_sp && m_output_sp && m_error_sp &&
               m_input_sp->GetIsRealTerminal();
```
The correct check is:

```
use_editline =
    m_input_sp && m_input_sp->GetIsRealTerminal() &&
    m_output_sp && m_output_sp->GetUnlockedFile().GetStream() &&
    m_error_sp && m_error_sp->GetUnlockedFile().GetStream();
```

We don't need to update the check for the input, because we're handling
the missing stream there correctly in the call to the constructor:

```
m_editline_up = std::make_unique<Editline>(
    editline_name, m_input_sp ? m_input_sp->GetStream() : nullptr,
    m_output_sp, m_error_sp, m_color);
```

We can't do the same for the output and error because we need to pass
the file, not the stream (to do proper locking).

As I was debugging this I added some more assertions. They're generally
useful so I'm keeping them.

Fixes #170891
2025-12-11 17:24:04 +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
Felipe de Azevedo Piovezan
f27fbca37c
[lldb][NFC] Replace const std::vector& with ArrayRef in APIs (#170834)
Inside the LLVM codebase, const vector& should just be ArrayRef, as this
more general API works both with vectors, SmallVectors and
SmallVectorImpl, as well as with single elements.

This commit replaces two uses introduced in
https://github.com/llvm/llvm-project/pull/168797 .
2025-12-08 16:59:32 +00:00
Med Ismail Bennani
96c733e0db
[lldb] Add support for PC-less scripted frames (#170805)
Scripted frames that materialize Python functions or other non-native
code are PC-less by design, meaning they don't have valid program
counter values. Previously, these frames would display invalid addresses
(`0xffffffffffffffff`) in backtrace output.

This patch updates `FormatEntity` to detect and suppress invalid address
display for PC-less frames, adds fallback to frame methods when symbol
context is unavailable, and modifies `StackFrame::GetSymbolContext` to
skip PC-based symbol resolution for invalid addresses.

The changes enable PC-less frames to display cleanly with proper
function names, file paths, and line numbers, and allow for source
display of foreign sources (like Python). Includes comprehensive test
coverage demonstrating frames pointing to Python source files.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-12-05 23:57:54 +00:00
n2h9
da4ea75336
[lldb] [disassembler] chore: enhance VariableAnnotator to return structured data: introduce VariableAnnotator::AnnotateStructured method (#169408)
## 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 introduces new method `AnnotateStructured` in
`VariableAnnotator` class, which returns the result as a vector of
`VariableAnnotation` structured data, compared to original `Annotate`.

Additionally structured data is enhanced with information inferred from
`DWARFExpressionEntry` and variable declaration data.

I have moved this part of functionality form a bigger pr
https://github.com/llvm/llvm-project/pull/165163 to make it easier to
review, deliver smaller chunk faster in an incremental way.

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

all tests (9 existing) are passing.

<details>
<summary>screenshot 2025-11-24</summary>
<img width="1344" height="875" alt="screenshot"
src="https://github.com/user-attachments/assets/863e0fca-1e3e-43dc-bfa3-4b78ce287ae6"
/>
</details>


<details>
<summary>screenshot 2025-11-26</summary>
<img width="1851" height="865" alt="image"
src="https://github.com/user-attachments/assets/d47dacee-a679-4a49-ab22-efb5a16fe29c"
/>
</details>

<details>
<summary>screenshot 2025-12-03</summary>
<img width="1592" height="922" alt="Screenshot From 2025-12-03 22-11-30"
src="https://github.com/user-attachments/assets/957ded3d-bea1-43d0-8241-d342dfc2c7b0"
/>
</details>

---------

Signed-off-by: Nikita B <n2h9z4@gmail.com>
Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
2025-12-04 13:56:26 -08:00
Augusto Noronha
d7fb086668
[lldb] Refactor LookupInfo object to be per-language (#168797)
Some months ago, the LookupInfo constructor logic was refactored to not
depend on language specific logic, and use languages plugins instead. In
this refactor, when the language type is unknown, a single LookupInfo
object will handle multiple languages. This doesn't work well, as
multiple languages might want to configure the LookupInfo object in
different ways. For example, different languages might want to set the
m_lookup_name differently from each other, but the previous
implementation would pick the first name a language provided, and
effectively ignored every other language. Other fields of the LookupInfo
object are also configured in incompatible ways.

This approach doesn't seem to be a problem upstream, since only the
C++/Objective-C language plugins are available, but it broke downstream
on the Swift fork, as adding Swift to the list of default languages when
the language type is unknown breaks C++ tests.

This patch makes it so instead of building a single LookupInfo object
for multiple languages, one LookupInfo object is built per language
instead.

rdar://159531216
2025-12-03 16:15:36 -08:00
Felipe de Azevedo Piovezan
2b725ab8bf
[lldb] Add DisassemblerLLVMC::IsBarrier API (#169632)
This will allow the instruction emulation unwinder to reason about
instructions that prevent the subsequent instruction from executing.

Part of a sequence of PRs:
[lldb][NFCI] Rewrite UnwindAssemblyInstEmulation in terms of a CFG visit
#169630
[lldb][NFC] Rename forward_branch_offset to branch_offset in
UnwindAssemblyInstEmulation #169631
[lldb] Add DisassemblerLLVMC::IsBarrier API #169632
[lldb] Handle backwards branches in UnwindAssemblyInstEmulation #169633

commit-id:bb5df4aa
2025-12-03 09:08:05 +00:00
Med Ismail Bennani
41a53c0a23
[lldb/Target] Add BorrowedStackFrame and make StackFrame methods virtual (#170191)
This change makes StackFrame methods virtual to enable subclass
overrides and introduces BorrowedStackFrame, a wrapper that presents an
existing StackFrame with a different frame index.

This enables creating synthetic frame views or renumbering frames
without copying the underlying frame data, which is useful for frame
manipulation scenarios.

This also adds a new borrowed-info format entity to show what was the
original frame index of the borrowed frame.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-12-02 10:41:03 -08:00
Jonas Devlieghere
c103d61758
[lldb] Fix a bug when disabling the statusline. (#169127)
Currently, disabling the statusline with `settings set show-statusline
false` leaves LLDB in a broken state. The same is true when trying to
toggle the setting again.

The issue was that setting the scroll window to 0 is apparently not
identical to setting it to the correct number of rows, even though some
documentation online incorrectly claims so.

Fixes #166608
2025-12-01 18:30:31 +00:00
n2h9
c4921b75a9
[lldb] [disassembler] chore: update VariableAnnotator::Annotate to except only Instruction as param and drop module and target (#168276) 2025-11-22 16:01:34 +00:00
Jonas Devlieghere
06eac9feb9
[lldb] Eliminate SupportFileSP nullptr derefs (#168624)
This patch fixes and eliminates the possibility of SupportFileSP ever
being nullptr. The support file was originally treated like a value
type, but became a polymorphic type and therefore has to be stored and
passed around as a pointer.

To avoid having all the callers check the validity of the pointer, I
introduced the invariant that SupportFileSP is never null and always
default constructed. However, without enforcement at the type level,
that's fragile and indeed, we already identified two crashes where
someone accidentally broke that invariant.

This PR introduces a NonNullSharedPtr to prevent that. NonNullSharedPtr
is a smart pointer wrapper around std::shared_ptr that guarantees the
pointer is never null. If default-constructed, it creates a
default-constructed instance of the contained type. Note that I'm using
private inheritance because you shouldn't inherit from standard library
classes due to the lack of virtual destructor. So while the new
abstraction looks like a `std::shared_ptr`, it is in fact **not** a
shared pointer. Given that our destructor is trivial, we could use
public inheritance, but currently there's no need for it.

rdar://164989579
2025-11-20 16:45:11 -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
Tom Yang
66d5f6a605
[lldb] fix parallel module loading deadlock for Linux DYLD (#166480)
Another attempt at resolving the deadlock issue @GeorgeHuyubo discovered
(his previous
[attempt](https://github.com/llvm/llvm-project/pull/160225)).

This change can be summarized as the following:
* Plumb through a boolean flag to force no preload in
`GetOrCreateModules` all the way through to `LoadModuleAtAddress`.
* Parallelize `Module::PreloadSymbols` separately from
`Target::GetOrCreateModule` and its caller `LoadModuleAtAddress` (this
is what avoids the deadlock).

These changes roughly maintain the performance characteristics of the
previous implementation of parallel module loading. Testing on targets
with between 5000 and 14000 modules, I saw similar numbers as before,
often more than 10% faster in the new implementation across multiple
trials for these massive targets. I think it's because we have less lock
contention with this approach.

# The deadlock

See [bt.txt](https://github.com/user-attachments/files/22524471/bt.txt)
for a sample backtrace of LLDB when the deadlock occurs.

As @GeorgeHuyubo explains in his
[PR](https://github.com/llvm/llvm-project/pull/160225), the deadlock
occurs from an ABBA deadlock that happens when a thread context-switches
out of `Module::PreloadSymbols`, goes into `Target::GetOrCreateModule`
for another module, possibly entering this block:
```
      if (!module_sp) {
        // The platform is responsible for finding and caching an appropriate
        // module in the shared module cache.
        if (m_platform_sp) {
          error = m_platform_sp->GetSharedModule(
              module_spec, m_process_sp.get(), module_sp, &search_paths,
              &old_modules, &did_create_module);
        } else {
          error = Status::FromErrorString("no platform is currently set");
        }
      }
```
`Module::PreloadSymbols` holds a module-level mutex, and then
`GetSharedModule` *attempts* to hold the mutex of the global shared
`ModuleList`. So, this thread holds the module mutex, and waits on the
global shared `ModuleList` mutex.

A competing thread may execute `Target::GetOrCreateModule`, enter the
same block as above, grabbing the global shared `ModuleList` mutex.
Then, in `ModuleList::GetSharedModule`, we eventually call
`ModuleList::FindModules` which eventually waits for the `Module` mutex
held by the first thread (via `Module::GetUUID`). Thus, we deadlock.

## Reproducing the deadlock

It might be worth noting that I've never been able to observe this
deadlock issue during live debugging (e.g. launching or attaching to
processes), however we were able to consistently reproduce this issue
with coredumps when using the following settings:
```
(lldb) settings set target.parallel-module-load true
(lldb) settings set target.preload-symbols true
(lldb) settings set symbols.load-on-demand false
(lldb) target create --core /some/core/file/here
# deadlock happens
```

## How this change avoids this deadlock

This change avoids concurrent executions of `Module::PreloadSymbols`
with `Target::GetOrCreateModule` by waiting until after the
`Target::GetOrCreateModule` executions to run `Module::PreloadSymbols`
in parallel. This avoids the ordering of holding a Module lock *then*
the ModuleList lock, as `Target::GetOrCreateModule` executions maintain
the ordering of the shared ModuleList lock first (from what I've read
and tested).

## Why not read-write lock?

Some feedback in https://github.com/llvm/llvm-project/pull/160225 was to
modify mutexes used in these components with read-write locks. This
might be a good idea overall, but I don't think it would *easily*
resolve this specific deadlock. `Module::PreloadSymbols` would probably
need a write lock to Module, so even if we had a read lock in
`Module::GetUUID` we would still contend. Maybe the `ModuleList` lock
could be a read lock that converts to a write lock if it chooses to
update the module, but it seems likely that some thread would try to
update the shared module list and then the write lock would contend
again.

Perhaps with deeper architectural changes, we could fix this issue?

# Other attempts

One downside of this approach (and the former approach of parallel
module loading) is that each DYLD would need to implement this pattern
themselves. With @clayborg's help, I looked at a few other approaches:
* In `Target::GetOrCreateModule`, backgrounding the
`Module::PreloadSymbols` call by adding it directly to the thread pool
via `Debugger::GetThreadPool().async()`. This required adding a lock to
`Module::SetLoadAddress` (probably should be one there already) since
`ObjectFileELF::SetLoadAddress` is not thread-safe (updates sections).
Unfortunately, during execution, this causes the preload symbols to run
synchronously with `Target::GetOrCreateModule`, preventing us from truly
parallelizing the execution.
* In `Module::PreloadSymbols`, backgrounding the `symtab` and `sym_file`
`PreloadSymbols` calls individually, but similar issues as the above.
* Passing a callback function like
https://github.com/swiftlang/llvm-project/pull/10746 instead of the
boolean I use in this change. It's functionally the same change IMO,
with some design tradeoffs:
* Pro: the caller doesn't need to explicitly call
`Module::PreloadSymbols` itself, and can instead call whatever function
is passed into the callback.
* Con: the caller needs to delay the execution of the callback such that
it occurs after the `GetOrCreateModule` logic, otherwise we run into the
same issue. I thought this would be trickier for the caller, requiring
some kinda condition variable or otherwise storing the calls to execute
afterwards.

# Test Plan:
```
ninja check-lldb
```

---------

Co-authored-by: Tom Yang <toyang@fb.com>
2025-11-14 15:58:43 -08:00
Alex Langford
897cc3ee42
[lldb][NFC] Remove plugin headers from Module (#167789)
As of e4a672bc17a2a, lldbCore is free of plugins. These headers are no
longer needed.
2025-11-12 16:19:17 -08:00
Michael Buch
54c9ddddd1
[libcxxabi][ItaniumDemangle] Separate GtIsGt counter into more states (#166578)
Currently `OutputBuffer::GtIsGt` is used to tell us if we're inside
template arguments and have printed a '(' without a closing ')'. If so,
we don't need to quote '<' when printing it as part of a binary
expression inside a template argument. Otherwise we need to. E.g.,
```
foo<a<(b < c)>> // Quotes around binary expression needed.
```

LLDB's `TrackingOutputBuffer` has heuristics that rely on checking
whether we are inside template arguments, regardless of the current
parentheses depth. We've been using `isGtInsideTemplateArgs` for this,
but that isn't correct. Resulting in us incorrectly tracking the
basename of function like:
```
void func<(foo::Enum)1>()
```
Here `GtIsGt > 0` despite us being inside template arguments (because we
incremented it when seeing '(').

This patch adds a `isInsideTemplateArgs` API which LLDB will use to more
accurately track parts of the demangled name.

To make sure this API doesn't go untested in the actual libcxxabi
test-suite, I changed the existing `GtIsGt` logic to use it. Also
renamed the various variables/APIs involved to make it (in my opinion)
more straightforward to understand what's going on. But happy to rename
it back if people disagree.

Also adjusted LLDB to use the newly introduced API (and added a
unit-test that would previously fail).
2025-11-07 07:52:03 +00:00
Jacob Lalonde
32ebf635c2
[LLDB] Fix debuginfo ELF files overwriting Unified Section List (#166635)
Recently I've been deep diving ELF cores in LLDB, aspiring to move LLDB
closer to GDB in capability. One issue I encountered was a system lib
losing it's unwind plan when loading the debuginfo. The reason for this
was the debuginfo has the eh_frame section stripped and the main
executable did not.

The root cause of this was this line in
[ObjectFileElf](163933e9e7/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (L1972))
```
  // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
  // unified section list.
  if (GetType() != eTypeDebugInfo)
    unified_section_list = *m_sections_up;
```

This would always be executed because CalculateType can never return an
eTypeDebugInfo
```
ObjectFile::Type ObjectFileELF::CalculateType() {
  switch (m_header.e_type) {
  case llvm::ELF::ET_NONE:
    // 0 - No file type
    return eTypeUnknown;

  case llvm::ELF::ET_REL:
    // 1 - Relocatable file
    return eTypeObjectFile;

  case llvm::ELF::ET_EXEC:
    // 2 - Executable file
    return eTypeExecutable;

  case llvm::ELF::ET_DYN:
    // 3 - Shared object file
    return eTypeSharedLibrary;

  case ET_CORE:
    // 4 - Core file
    return eTypeCoreFile;

  default:
    break;
  }
  return eTypeUnknown;
}
```

This makes sense as there isn't a explicit sh_type to denote that this
file is a debuginfo. After some discussion with @clayborg and
@GeorgeHuyubo we settled on joining the exciting unified section list
with whatever new sections were being added. Adding each new unique
section, or taking the section with the maximum file size. We picked
this strategy to pick the section with the most information. In most
scenarios, LHS should be SHT_NOBITS and RHS would be SHT_PROGBITS.

Here is a diagram documenting the existing vs proposed new way.
<img width="1666" height="1093" alt="image"
src="https://github.com/user-attachments/assets/73ba9620-c737-439e-9934-ac350d88a3b5"
/>
2025-11-06 15:56:11 -08:00
Augusto Noronha
aa1b1dc391
[lldb] Add function to tell if a section is a GOT section (#165936)
A global offset table is a section that holds the address of functions
that are dynamically linked. The Swift plugin needs to know if sections
are a global offset table or not.
2025-11-06 12:52:04 -08:00
GeorgeHuyubo
fce58897ce
[lldb] Enable locate module callback for all module loading (#160199)
Main executables were bypassing the locate module callback that shared 
libraries use, preventing custom symbol file location logic from working
consistently. 

This PR fix this by
*   Adding target context to ModuleSpec
* Leveraging that context to use target search path and platform's
locate module callback in ModuleList::GetSharedModule

This ensures both main executables and shared libraries get the same 
callback treatment for symbol file resolution.

---------

Co-authored-by: George Hu <hyubo@meta.com>
Co-authored-by: George Hu <georgehuyubo@gmail.com>
2025-11-06 12:48:21 -08:00
Med Ismail Bennani
71cb0bb893
[lldb/Target] Add SyntheticFrameProvider class (#166664)
This patch introduces a new way to reconstruct the thread stackframe
list.

New `SyntheticFrameProvider` classes can lazy fetch a StackFrame at
index using a provided StackFrameList.

In can either be the real unwinder StackFrameList or we could also chain
SyntheticFrameProviders to each others.

This is the foundation work to implement ScriptedFrameProviders, which
will come in a follow-up patch.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-11-06 11:37:42 -08:00
Jonas Devlieghere
22d2f7f38e
[lldb] Emit a progress event from the source manager (#165802)
Reading a source file might take a while, for example because it's
located on a virtual file system that's fetching the data on demand.

This PR emits a progress event to convey this to the user when reading
the file exceeds a certain threshold (500ms). Although it doesn't speed
up the operation, it still greatly improves the user experience by
helping them understand what's going on.

rdar://163750392
2025-10-31 13:10:09 -07:00
Timur Golubovich
5d7da0a5cd
[lldb] Added a warning in case of instruction decode failure (#164413)
While testing baremetal lldb, I came across a situation that if an
instruction could not be disassembled, lldb will print nothing as an
output which might be a bit strange. I added at least printing warning
in this case.
2025-10-23 15:26:14 +01: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
Augusto Noronha
8523c6a448
[lldb] Actually use new SharedModuleList class (#162574)
Now that the use after free bug has been fixed (397181d5c), actually use
the new SharedModuleList class.
2025-10-09 10:39:45 -07:00
Augusto Noronha
397181d5c1
[lldb] Fix use after free on ModuleList::RemoveSharedModuleIfOrphaned (#155331)
This fixes a potential use after free where
ModuleList::RemoveSharedModuleIfOrphaned ->
SharedModuleList::RemoveIfOrphaned -> SharedModuleList::RemoveFromMap
would potentially dereference a freed pointer. This fixes it by not
calling ModuleList::RemoveSharedModuleIfOrphaned at all if the pointer
was just freed.
2025-10-08 15:35:24 -07:00
Ebuka Ezike
8e62acec9e
[lldb] Ignore trailing spaces on quit confirmation (#162263) 2025-10-08 18:48:20 +01:00
Michael Buch
3d810086d1
[lldb][Lanugage][NFC] Adapt Language::ForEach to IterationAction (#161830) 2025-10-03 15:47:21 +01:00
Michael Buch
5c50bdcea3 [lldb][Mangled][NFC] Remove redundant const-qualifier on llvm::StringRef argument 2025-10-01 11:07:23 +01: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
Med Ismail Bennani
84b56202fb
[lldb] Introduce ScriptedFrame affordance (#149622)
This patch introduces a new scripting affordance in lldb:
`ScriptedFrame`.

This allows user to produce mock stackframes in scripted threads and
scripted processes from a python script.

With this change, StackFrame can be synthetized from different sources:
- Either from a dictionary containing a load address, and a frame index,
  which is the legacy way.
- Or by creating a ScriptedFrame python object.

One particularity of synthezising stackframes from the ScriptedFrame
python object, is that these frame have an optional PC, meaning that
they don't have a report a valid PC and they can act as shells that just
contain static information, like the frame function name, the list of
variables or registers, etc. It can also provide a symbol context.

rdar://157260006

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-09-04 15:07:11 -07:00
Med Ismail Bennani
6c10ab8a3c
[lldb] Mark scripted frames as synthetic instead of artificial (#153117)
This patch changes the way frames created from scripted affordances like
Scripted Threads are displayed. Currently, they're marked artificial
which is used usually for compiler generated frames.

This patch changes that behaviour by introducing a new synthetic
StackFrame kind and moves 'artificial' to be a distinct StackFrame
attribut.

On top of making these frames less confusing, this allows us to know
when a frame was created from a scripted affordance.

rdar://155949703

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-09-03 15:58:14 -07:00
Abdullah Mohammad Amin
d39772cb05
[lldb] Refactor variable annotation logic in Disassembler::PrintInstructions (#156118)
This patch is a follow-up to
[#152887](https://github.com/llvm/llvm-project/pull/152887), addressing
review comments that came in after the original change was merged.

- Move `VarState` definition out of `PrintInstructions` into a private
helper, with member comments placed before fields.
- Introduce a `VariableAnnotator` helper class to encapsulate state and
logic for live variable tracking across instructions.
- Replace `seen_this_inst` flag with a map-diff approach: recompute the
current variable set per instruction and diff against the previous set.
- Use `nullptr` instead of an empty `ProcessSP` when calling
`ABI::FindPlugin`.
- Narrow `Block*` scope with `if (Block *B = ...)`.
- Set `DIDumpOptions::PrintRegisterOnly` directly from
`static_cast<bool>(abi_sp)`.
- Prefer `emplace_back` over `push_back` for event strings.
- General cleanup to match LLVM coding style and reviewer feedback.

This makes the annotation code easier to read and consistent with
LLVM/LLDB conventions while preserving functionality.
2025-08-30 13:17:05 -07:00
Jonas Devlieghere
df4c367585
[lldb] Stop the protocol servers when terminating the plugin (#156101)
Currently, the server keeps running until we call Stop from its dtor in
the static destruction chain. This is too late: the server should stop
when the plugin gets terminated.
2025-08-29 15:41:44 -07:00
Jonas Devlieghere
2a062d6936
[lldb] Add SBFunction::GetBaseName() & SBSymbol::GetBaseName() (#155939)
When you are trying for instance to set a breakpoint on a function by
name, but the SBFunction or SBSymbol are returning demangled names with
argument lists, that match can be tedious to do. Internally, the base
name of a symbol is something we handle all the time, so it's reasonable
that there should be a way to get that info from the API as well.

rdar://159318791
2025-08-28 19:10:52 -07:00
Abdullah Mohammad Amin
8ec4db5e17
Stateful variable-location annotations in Disassembler::PrintInstructions() (follow-up to #147460) (#152887)
**Context**  
Follow-up to
[#147460](https://github.com/llvm/llvm-project/pull/147460), which added
the ability to surface register-resident variable locations.
This PR moves the annotation logic out of `Instruction::Dump()` and into
`Disassembler::PrintInstructions()`, and adds lightweight state tracking
so we only print changes at range starts and when variables go out of
scope.

---

## What this does

While iterating the instructions for a function, we maintain a “live
variable map” keyed by `lldb::user_id_t` (the `Variable`’s ID) to
remember each variable’s last emitted location string. For each
instruction:

- **New (or newly visible) variable** → print `name = <location>` once
at the start of its DWARF location range, cache it.
- **Location changed** (e.g., DWARF range switched to a different
register/const) → print the updated mapping.
- **Out of scope** (was tracked previously but not found for the current
PC) → print `name = <undef>` and drop it.

This produces **concise, stateful annotations** that highlight variable
lifetime transitions without spamming every line.

---

## Why in `PrintInstructions()`?

- Keeps `Instruction` stateless and avoids changing the
`Instruction::Dump()` virtual API.
- Makes it straightforward to diff state across instructions (`prev →
current`) inside the single driver loop.

---

## How it works (high-level)

1. For the current PC, get in-scope variables via
`StackFrame::GetInScopeVariableList(/*get_parent=*/true)`.
2. For each `Variable`, query
`DWARFExpressionList::GetExpressionEntryAtAddress(func_load_addr,
current_pc)` (added in #144238).
3. If the entry exists, call `DumpLocation(..., eDescriptionLevelBrief,
abi)` to get a short, ABI-aware location string (e.g., `DW_OP_reg3 RBX →
RBX`).
4. Compare against the last emitted location in the live map:
   - If not present → emit `name = <location>` and record it.
   - If different → emit updated mapping and record it.
5. After processing current in-scope variables, compute the set
difference vs. the previous map and emit `name = <undef>` for any that
disappeared.

Internally:
- We respect file↔load address translation already provided by
`DWARFExpressionList`.
- We reuse the ABI to map LLVM register numbers to arch register names.

---

## Example output (x86_64, simplified)

```
->  0x55c6f5f6a140 <+0>:  cmpl   $0x2, %edi                                                         ; argc = RDI, argv = RSI
    0x55c6f5f6a143 <+3>:  jl     0x55c6f5f6a176            ; <+54> at d_original_example.c:6:3
    0x55c6f5f6a145 <+5>:  pushq  %r15
    0x55c6f5f6a147 <+7>:  pushq  %r14
    0x55c6f5f6a149 <+9>:  pushq  %rbx
    0x55c6f5f6a14a <+10>: movq   %rsi, %rbx
    0x55c6f5f6a14d <+13>: movl   %edi, %r14d
    0x55c6f5f6a150 <+16>: movl   $0x1, %r15d                                                        ; argc = R14
    0x55c6f5f6a156 <+22>: nopw   %cs:(%rax,%rax)                                                    ; i = R15, argv = RBX
    0x55c6f5f6a160 <+32>: movq   (%rbx,%r15,8), %rdi
    0x55c6f5f6a164 <+36>: callq  0x55c6f5f6a030            ; symbol stub for: puts
    0x55c6f5f6a169 <+41>: incq   %r15
    0x55c6f5f6a16c <+44>: cmpq   %r15, %r14
    0x55c6f5f6a16f <+47>: jne    0x55c6f5f6a160            ; <+32> at d_original_example.c:5:10
    0x55c6f5f6a171 <+49>: popq   %rbx                                                               ; i = <undef>
    0x55c6f5f6a172 <+50>: popq   %r14                                                               ; argv = RSI
    0x55c6f5f6a174 <+52>: popq   %r15                                                               ; argc = RDI
    0x55c6f5f6a176 <+54>: xorl   %eax, %eax
    0x55c6f5f6a178 <+56>: retq  
```

Only transitions are shown: the start of a location, changes, and
end-of-lifetime.

---

## Scope & limitations (by design)

- Handles **simple locations** first (registers, const-in-register cases
surfaced by `DumpLocation`).
- **Memory/composite locations** are out of scope for this PR.
- Annotations appear **only at range boundaries** (start/change/end) to
minimize noise.
- Output is **target-independent**; register names come from the target
ABI.

## Implementation notes

- All annotation printing now happens in
`Disassembler::PrintInstructions()`.
- Uses `std::unordered_map<lldb::user_id_t, std::string>` as the live
map.
- No persistent state across calls; the map is rebuilt while walking
instruction by instruction.
- **No changes** to the `Instruction` interface.

---

## Requested feedback

- Placement and wording of the `<undef>` marker.
- Whether we should optionally gate this behind a setting (currently
always on when disassembling with an `ExecutionContext`).
- Preference for immediate inclusion of tests vs. follow-up patch.

---

Thanks for reviewing! Happy to adjust behavior/format based on feedback.

---------

Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
Co-authored-by: Adrian Prantl <adrian.prantl@gmail.com>
2025-08-28 10:41:38 -07:00
Augusto Noronha
3c91d58040
Revert "[NFC][lldb] Add a null check, actually use new SharedModuleLi… (#155327)
…st class"

This reverts commit 234e075c1dbdaacd2e1b4199ae983f5c4439223c.


I'm reverting this because the ASAN build fails running the
TestMiniDumpUUID.py test. This happens because the pointer is already
freed before the call to `RemoveIfOrpahaned`. The ModuleList
implementation never actually dereferences the pointer, so it worked
correctly, but the new map implementation does dereference it, hence the
crash.
2025-08-25 17:21:47 -07:00
Augusto Noronha
1eac656bad
[NFC][lldb] Add a null check, actually use new SharedModuleList class (#155006)
Add a missing null check pointed out in the previous PR review, and
actually use the SharedModuleList class, which was introduced but
unused.
2025-08-22 11:29:11 -07:00
nerix
d6fcaef281
[LLDB][Value] Require type size when reading a scalar (#153386)
When reading a value as a scalar, the type size is required. It's
returned as a `std::optional`. This optional isn't checked for scalar
values, where it is unconditionally accessed.

This came up in the
[Shell/Process/Windows/msstl_smoke.cpp](4e10b62442/lldb/test/Shell/Process/Windows/msstl_smoke.cpp)
test. There, LLDB breaks at the function entry, so all locals aren't
initialized yet. Most values will contain garbage. The [`std::list`
synthetic
provider](4e10b62442/lldb/source/Plugins/Language/CPlusPlus/GenericList.cpp (L517))
tries to read the value using `GetData`. However, in
[`ValueObject::GetData`](4e10b62442/lldb/source/ValueObject/ValueObject.cpp (L766)),
[`ValueObjectChild::UpdateValue`](88c993fbc5/lldb/source/ValueObject/ValueObjectChild.cpp (L102))
fails because the parent already failed to read its data, so `m_value`
won't have a compiler type, thus the size can't be read.
2025-08-22 12:26:03 +02:00
David Spickett
b3396c5e96
[lldb] Account for registers being host endian when casting values (#150011)
Fixes https://github.com/llvm/llvm-project/issues/135707

Follow up to https://github.com/llvm/llvm-project/pull/148836
which fixed some of this issue but not all of it. 

Our Value/ValueObject system does not store the endian directly
in the values. Instead it assumes that the endian of the result
of a cast can be assumed to be the target's endian, or the host
but only as a fallback. It assumes the place it is copying from
is also that endian.

This breaks down when you have register values. These are always
host endian and continue to be when cast. Casting them to big 
endian when on a little endian host breaks certain calls like
GetValueAsUnsigned.

To fix this, check the context of the value. If it has a register
context, always treat it as host endian and make the result host
endian.

I had an alternative where I passed an "is_register" flag into
all calls to this, but it felt like a layering violation and changed
many more lines.

This solution isn't much more robust, but it works for all the test
cases I know of. Perhaps you can create a register value without
a RegisterInfo backing it, but I don't know of a way myself.

For testing, I had to add a minimal program file for each arch
so that there is a type system to support the casting. This is
generated from YAML since we only need the machine and endian
to be set.
2025-08-13 14:58:29 +01:00
Augusto Noronha
bd1b1a5e1a
Reland "[NFC][lldb] Speed up lookup of shared modules" (229d860) (#152607)
The previous commit was reverted because it broke a test on the bots.

Original commit message:

By profiling LLDB debugging a Swift application without a dSYM and a
large amount of .o files, I identified that querying shared modules was
the biggest bottleneck when running "frame variable", and Clang types
need to be searched.

One of the reasons for that slowness is that the shared module list can
can grow very large, and the search through it is O(n).

To solve this issue, this patch adds a new hashmap to the shared module
list whose key is the name of the module, and the value is all the
modules that share that name. This should speed up any search where the
query contains the module name.

rdar://156753350
2025-08-12 13:12:55 -07:00
Jonas Devlieghere
5be2063e10
[lldb] Support parsing the Wasm symbol table (#153093)
This PR adds support for parsing the WebAssembly symbol table. The
symbol table is encoded in the "names" section and contains names and
indexes into other sections. For now we only support parsing function
(code) symbols. The result is that you can set breakpoints by symbol
name, while previously breakpoints by name required debug info (DWARF).

This is also necessary for Swift, which checks for the presence of
`swift_release` as a heuristic to determine if there's a static Swift
stdlib.
2025-08-12 15:12:30 -05:00
Ely Ronnen
4d3feaea66
[lldb-dap] persistent assembly breakpoints (#148061)
Resolves #141955

- Adds data to breakpoints `Source` object, in order for assembly
breakpoints, which rely on a temporary `sourceReference` value, to be
able to resolve in future sessions like normal path+line breakpoints
- Adds optional `instructions_offset` parameter to `BreakpointResolver`
2025-08-08 22:29:47 +02:00
Dominic Chen
92ac1ac904
[lldb] Fix incorrect print of UUID and load address (#152560)
The current display is missing a space, for example:
```
no target │ Locating binary: 24906A83-0182-361B-8B4A-90A249B04FD7at 0x0000000c0d108000
```

Co-authored-by: Dominic Chen <daming_chen@apple.com>
2025-08-07 21:31:48 -07:00
Augusto Noronha
75cc77e55e
Revert "[NFC][lldb] Speed up lookup of shared modules (#152054)" (#152582)
This reverts commit 229d86026fa0e5d9412a0d5004532f0d9733aac6.
2025-08-07 12:49:47 -07:00
Augusto Noronha
229d86026f
[NFC][lldb] Speed up lookup of shared modules (#152054)
By profiling LLDB debugging a Swift application without a dSYM and a
large amount of .o files, I identified that querying shared modules was
the biggest bottleneck when running "frame variable", and Clang types
need to be searched.

One of the reasons for that slowness is that the shared module list can
grow very large, and the search through it is O(n).

To solve this issue, this patch adds a new hashmap to the shared module
list whose key is the name of the module, and the value is all the
modules that share that name. This should speed up any search where the
query contains the module name.

rdar://156753350
2025-08-07 11:12:38 -07:00
Michael Buch
fac7453d2c
[lldb][Mangled] Move SuffixRange computation into TrackingOutputBuffer (#152483)
This way all the tracking is self-contained in `TrackingOutputBuffer`
and we can test the `SuffixRange` properly.
2025-08-07 14:39:52 +01:00