1433 Commits

Author SHA1 Message Date
David Peixotto
44a1f7e7ca
[lldb] Fix unsafe map mutation in ProcessElfCore::FindModuleUUID (#159444)
The `ProcessElfCore::FindModuleUUID` function can be called by multiple
threads at the same time when `target.parallel-module-load` is true. We
were using the `operator[]` to lookup the UUID which will mutate the map
when the key is not present. This is unsafe in a multi-threaded contex
so we now use a read-only `find` operation and explicitly return an
invalid UUID when the key is not present.

The `m_uuids` map can follow a create-then-query pattern. It is
populated in the `DoLoadCore` function which looks like it is only
called in a single-threaded context so we do not need extra locking as
long as we keep the other accesses read-only.

Other fixes I considered

* Use a lock to protect access - We don't need to modify the map after
creation so we can allow concurrent read-only access.
* Store the map in a const pointer container to prevent accidental
mutation in other places.
     - Only accessed in one place currently so just added a comment.
* Store the UUID in the NT_FILE_Entry after building the mapping
correctly in `UpdateBuildIdForNTFileEntries`. - The map lets us avoid a
linear search in `FindModuleUUID`.

This commit also reverts the temporary workaround from #159395 which
disabled parallel module loading to avoid the test failure.

Fixes #159377
2025-09-18 08:20:09 -07:00
David Spickett
d0bdc5d945
[lldb][test] Disable parallel module loading for TestNetBSDCore.py (#159395)
Since #157170 this test has been flakey on several LLDB buildbots. I
suspect it's to do with mutli-threading, there are more details in
#159377.

Disable parallel loading for now so we are not spamming people making
unrelated changes.
2025-09-17 17:40:36 +01:00
Sirraide
9b95e10d5e
[LLDB] [Tests] Downgrade -Wincompatible-pointer-types to a warning in some tests (#158756)
These no longer compile because the warning now defaults to an error
after #157364, so downgrade the error to a warning for now; I’m not
familiar enough with either LLDB or MacOS to fix these warnings properly
(assuming they’re unintended).
2025-09-16 02:02:01 +02:00
Sirraide
b24769855d
[Clang] [Sema] Make -Wincompatible-pointer-types an error by default (#157364)
GCC 14 also made this an error by default, so we’re following suit.

Fixes #74605
2025-09-15 16:55:00 +00:00
Ebuka Ezike
5e118eca93
[lldb][test] Fix unordered-map test. (#158286)
The build step is overidden so it uses `libstdc++` instead of `libc++`
on linux
2025-09-15 15:21:56 +01:00
Jason Molenda
20e55f359d [lldb][NFC] Mark API test skipIfRemote to avoid a bot
The lldb-remote-linux-ubuntu bot (and only this bot) is still failing
for TestCortexMExceptionUnwind.py because the Target triple is
somehow inheriting a non-Darwin OS.  I marked this API test
skipUnlessDarwin but this bot can be identified more specifically
by a skipIfRemote test.  There's no benefit to running this test
remotely anyway; it doesn't execute any code.
2025-09-11 14:19:44 -07:00
Jason Molenda
6a71938770 Revert "[lldb][NFC] Force some logging on to TestCortexMExceptionUnwind.py"
This reverts commit 336503c4e1cdb5eaefde0536a34f0a95bc0c57bf.
2025-09-10 22:58:30 -07:00
Jason Molenda
336503c4e1 [lldb][NFC] Force some logging on to TestCortexMExceptionUnwind.py
to possibly debug why this test fails on the
lldb-remote-linux-ubuntu CI bot.  I'm sure the Target ArchSpec is
somehow ending up _not_ armv7m-apple-* like it should be, but I'd
like to gather a little more info before I just give up on running
this test on linux systems.
2025-09-10 22:43:24 -07:00
Jason Molenda
21857ae337 Revert "[lldb][NFC] Try to adapt Cortex-M API test for an Unbuntu bot"
This reverts commit 4eadb45f83cef00165055f8038f179ca5c3e88ef.
2025-09-10 17:44:56 -07:00
Jason Molenda
4eadb45f83 [lldb][NFC] Try to adapt Cortex-M API test for an Unbuntu bot
When I added support for the Cortex-M exception return unwinding,
I got CI test failures on the lldb-remote-linux-ubuntu bot.  The
triple from my test `binary.json`, "armv7m-apple", was not being
used for the Target, so the incorrect SysV / AAPCS ABI was being
selected, and that ABI plugin has default unwind plans that hardcode
the arm-code r11 frame pointer behavior.  This is a Cortex-M
core, and r7 should be used.  The Darwin Arm ABI plugin uses r7 for
both arm and thumb, and behaves correctly.

Try getting the triple from `binary.json` in the API test, creating
the target with that triple explicitly before loading the corefile.
This may help prevent however we were losing the "-apple-" part of
the triple.  We'll see what the CI bot looks like with this added.
2025-09-10 17:15:02 -07:00
Ebuka Ezike
55e99efdf1
[lldb][test] skip test TestRerunAndExprDylib.py on remote (#157916) 2025-09-10 20:26:36 +01:00
Ebuka Ezike
f5315bd135
[lldb][test] Re-enable TestRerunAndExprDylib.py (#157872)
the `skipTestIfFn` requires a function that return a string to skip or
None to run the test. The `isUbuntu18_04` function returns a bool and
the test is skipped on all platforms.



25ebdfe0ab/lldb/packages/Python/lldbsuite/test/decorators.py (L145-L157)
2025-09-10 17:23:17 +01:00
Ebuka Ezike
a65aca6201
[lldb][test] StepUntil disable test for unsupported linkers. (#157474)
`INSERT BEFORE` keyword is not supported in current versions gold and
mold linkers. Since we cannot confirm accurately what linker and version
is available on the system and when it will be supported. We test it
with a sample program using the script keywords.
2025-09-10 17:18:43 +01:00
Jason Molenda
f3b7ad4859 [lldb][NFC] Update testsuite skip comment
to explain why the skip was added.
2025-09-09 16:47:26 -07:00
Jason Molenda
e320d9bdd3 [lldb] Skip TestCortexMExceptionUnwind except Darwin
I'm getting a failure on one linux CI, lldb-remote-linux-ubuntu,
where the test of assertEqual(thread.GetNumFrames(), 6) fails
because the unwinder only has one frame, most likely the
target triple is not set to armv7m-apple-* so ABISysV_arm is
being used instead of ABIMacOSX_arm and the architecture default
unwind plans behave differently.  Possibly the frame pointer
register, or possibly the way the arch default unwind plans are
structured.

Skipping on linux for now until I can debug further.  Can repo on
Darwin by changing the binary.json `"triple": "armv7m-apple"` to
armv7m-linux.
2025-09-09 15:32:33 -07:00
jimingham
2669fdeee2
NFC: SBThread should not be the one to compute StopReasonData. (#157577)
This is something the StopInfo class manages, so it should be allowed to
compute this rather than having SBThread do so. This code just moves the
computation to methods in StopInfo. It is mostly NFC. The one change
that I actually had to adjust the tests for was a couple of tests that
were asking for the UnixSignal stop info data by asking for the data at
index 1. GetStopInfoDataCount returns 1 and we don't do 1 based indexing
so the test code was clearly wrong. But I don't think it makes sense to
perpetuate handing out the value regardless of what index you pass us.
2025-09-09 15:31:55 -07:00
Jason Molenda
78dfbcaa7b [lldb][NFC] add comment to new TestCortexMExceptionUnwind 2025-09-09 14:27:25 -07:00
Jason Molenda
69511ae804
[lldb] Unwind through ARM Cortex-M exceptions automatically (#153922)
When a processor faults/is interrupted/gets an exception, it will stop
running code and jump to an exception catcher routine. Most processors
will store the pc that was executing in a system register, and the
catcher functions have special instructions to retrieve that & possibly
other registers. It may then save those values to stack, and the author
can add .cfi directives to tell lldb's unwinder where to find those
saved values.

ARM Cortex-M (microcontroller) processors have a simpler mechanism where
a fixed set of registers are saved to the stack on an exception, and a
unique value is put in the link register to indicate to the caller that
this has taken place. No special handling needs to be written into the
exception catcher, unless it wants to inspect these preserved values.
And it is possible for a general stack walker to walk the stack with no
special knowledge about what the catch function does.

This patch adds an Architecture plugin method to allow an Architecture
to override/augment the UnwindPlan that lldb would use for a stack
frame, given the contents of the return address register. It resembles a
feature where the LanguageRuntime can replace/augment the unwind plan
for a function, but it is doing it at offset by one level. The
LanguageRuntime is looking at the local register context and/or symbol
name to decide if it will override the unwind rules. For the Cortex-M
exception unwinds, we need to modify THIS frame's unwind plan if the
CALLER's LR had a specific value. RegisterContextUnwind has to retrieve
the caller's LR value before it has completely decided on the UnwindPlan
it will use for THIS stack frame.

This does mean that we will need one additional read of stack memory
than we currently do when unwinding, on Armv7 Cortex-M targets. The
unwinder walks the stack lazily, as stack frames are requested, and so
now if you ask for 2 stack frames, we will read enough stack to walk 2
frames, plus we will read one extra word of memory, the spilled LR value
from the stack. In practice, with 512-byte memory cache reads, this is
unlikely to be a real performance hit.

This PR includes a test with a yaml corefile description and a JSON
ObjectFile, incorporating all of the necessary stack memory and symbol
names from a real debug session I worked on. The architectural default
unwind plans are used for all stack frames except the 0th because
there's no instructions for the functions, and no unwind info. I may
need to add an encoding of unwind fules to ObjectFileJSON in the future
as we create more test cases like this.

This PR depends on the yaml2macho-core utility from
https://github.com/llvm/llvm-project/pull/153911 to run its API test.

rdar://110663219
2025-09-09 14:11:39 -07:00
David Spickett
157e886374
[lldb][test] Prevent TestqOffsets.py picking up host binaries (#157432)
Due to a fallback in GDBRemoteCommunicationClient.cpp, on Linux we will
assume a PID of 1 if the remote does not respond in some way that tells
us the real PID.

So if PID 1 happened to be a process that the current user could read,
we would try to debug that instead. On my current machine, PID 1 was
sshd run by root so we would ignore it. If I changed the fallback to
some process ID run by my user, the test would fail.

To prevent this, select the remote-linux platform before creating the
target. This means we won't attempt any host lookups.

Fixes #155895
2025-09-09 09:30:29 +01:00
Igor Kudrin
8ec4d87550
[lldb][elf-core][ARM] Add support for VFP registers (#155956)
This patch loads values of the VFP registers from the NT_ARM_VFP note.

Note that a CORE/NT_FPREGSET note is typically present in core dump
files and is used to store the FPA registers. The FPA unit is rare and
obsolete; however, Linux creates the note even if the unit is absent.
2025-09-08 14:55:54 -07:00
Michael Buch
5326b3b176 [lldb][test] Only assert function name is in user-code on Darwin platforms
The frame recognizer for the instrumentation runtimes (added in
https://github.com/llvm/llvm-project/pull/133079) only triggers on Darwin
for `libclang_rt`. Adjust the tests accordingly.
2025-09-08 22:48:34 +01:00
Michael Buch
bdf645bb9b [lldb][test] TestTsanBasic.py: fix function name assertion
Since https://github.com/llvm/llvm-project/pull/133079 we no longer stop
in the stanitizer library when hitting a sanitizer breakpoint. Adjust
the test accordingly.
2025-09-08 19:27:18 +01:00
Michael Buch
879f40ab04
[lldb][Instrumentation] Set selected frame to outside sanitizer libraries (#133079)
When hitting a sanitizer breakpoint, LLDB currently displays the frame
in the sanitizer dylib (which we usually don't have debug-info for),
which isn't very helpful to the user. A more helpful frame to display
would be the first frame not in the sanitizer library (we have a
[similar heuristic when we trap inside
libc++](https://github.com/llvm/llvm-project/pull/108825)). This patch
does just that, by implementing the `GetSuggestedStackFrameIndex` API

Depends on https://github.com/llvm/llvm-project/pull/133078
2025-09-08 17:03:31 +00:00
Michael Buch
4b362f152e
[lldb][DataFormatter] Allow std::string formatters to match against custom allocators (#156050)
This came up in https://github.com/llvm/llvm-project/issues/155691.

For `std::basic_string` our formatter matching logic required the
allocator template parameter to be a `std::allocator`. There is no
compelling reason (that I know of) why this would be required for us to
apply the existing formatter to the string. We don't check the
`allocator` parameter for other STL containers either. This meant that
`std::string` that used custom allocators wouldn't be formatted. This
patch relaxes the regex for `basic_string`.
2025-09-05 09:24:50 +01:00
Jonas Devlieghere
820f440274
[lldb] Correct style of error messages (#156774)
The LLVM Style Guide says the following about error and warning messages
[1]:

> [T]o match error message styles commonly produced by other tools,
> start the first sentence with a lowercase letter, and finish the last
> sentence without a period, if it would end in one otherwise.

I often provide this feedback during code review, but we still have a
bunch of places where we have inconsistent error message, which bothers
me as a user. This PR identifies a handful of those places and updates
the messages to be consistent.

[1] https://llvm.org/docs/CodingStandards.html#error-and-warning-messages
2025-09-04 16:37:41 -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
Jonas Devlieghere
2498f0bcf5
[lldb] Add more command option mnemonics (#155705)
Add a bunch of mnemonics to the command options now that they're
highlighted in the help output. This uncovered two issues:

 - We had an instance where we weren't applying the ANSI formatting.
 - We had a place where we were now incorrectly computing the column
   width.

Both are fixed by this PR.
2025-09-04 13:21:24 -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
599d353938
[lldb] Restrict TestVariableAnnotationsDisassembler.py to ELF x86_64 (skip on Windows/COFF) (#156026)
The `TestVariableAnnotationsDisassembler.py` test assembles
`d_original_example.s`,
which contains ELF-specific directives such as:

- `.ident`
- `.section ".note.GNU-stack", "", @progbits`
- `.section .debug_line, "", @progbits`

These directives are not understood by COFF on Windows, so the test
fails
on the lldb-remote-linux-win builder even when running on x86_64.

This patch adds a decorator to gate the test,
- `@skipUnlessPlatform(["linux", "freebsd", "netbsd", "android"])` — 
  runs only on ELF platforms

Follow-up to #155942.
2025-08-29 16:23:07 +01:00
Abdullah Mohammad Amin
d3517b65b9
[lldb] Skip TestVariableAnnotationsDisassembler.py on non-x86 architectures (#155942)
The test lldb-api::TestVariableAnnotationsDisassembler.py was failing on
the lldb-remote-linux-ubuntu and lldb-remote-linux-win builders due to
assembler incompatibilities in d_original_example.s. These failures are
not related to the disassembler changes themselves but to the test
setup.

This patch updates the test to be skipped when running on unsupported
architectures to avoid failures. The test will still run and validate
correctly where the assembler input is supported.
2025-08-29 11:25:36 +01: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
Ebuka Ezike
7db1b2ad1e
[lldb][test] Run ranges::ref_vew test only for libc++ (#155813)
Remove redundant build step in std::ranges::ref_view test, this causes
it use `libstdc++` on linux instead of `libc++` .
2025-08-28 12:14:07 +01:00
David Spickett
4fc8bffbaa [lldb][test] Disable statusline module deadlock test on Linux
It has been flaky in CI and Linaro's AArch64 Linux bot.

See #154763.
2025-08-28 08:58:22 +00:00
Michael Buch
20dd053160
[lldb][DataFormatters] Support newer _LIBCPP_COMPRESSED_PAIR layout (#155153)
Starting with https://github.com/llvm/llvm-project/pull/154686 the
compressed_pair children are now wrapped in an anonymous structure.

This patch adjusts the LLDB data-formatters to support that.

Outstanding questions:
1. Should GetChildMemberWithName look through anonymous structures? That
will break users most likely. But maybe introducing a new API is worth
it? Then we wouldnt have to do this awkward passing around of
`anon_struct_index`
2. Do we support the layout without the anonymous structure? It's not
too much added complexity. And we did release that version of libc++, so
there is code out there compiled against it. But there is no great way
of testing it (some of our macOS matrix bots do test it i suppose, but
not in a targeted way). We have the layout "simulator" tests for some of
the STL types which I will adjust.
2025-08-25 09:17:55 -07:00
Julian Lettner
484d0408f9
[lldb] Fix source line annotations for libsanitizers traces (#154247)
When providing allocation and deallocation traces,
the ASan compiler-rt runtime already provides call
addresses (`TracePCType::Calls`).

On Darwin, system sanitizers (libsanitizers)
provides return address.  It also discards a few
non-user frames at the top of the stack, because
these internal libmalloc/libsanitizers stack
frames do not provide any value when diagnosing
memory errors.

Introduce and add handling for
`TracePCType::ReturnsNoZerothFrame` to cover this
case and enable libsanitizers traces line-level
testing.

rdar://157596927

---
Commit 1 is a mechanical refactoring to introduce
and adopt `TracePCType` enum to replace
`pcs_are_call_addresses` bool.  It preserve the
current behavior:
```
pcs_are_call_addresses:
  false  ->  TracePCType::Returns (default)
  true   ->  TracePCType::Calls
``` 

Best reviewed commit by commit.
2025-08-20 14:33:27 -07:00
Jonas Devlieghere
4cecbeed4f
[lldb] Support error variations in TestProcessCrashInfo.py (#154202)
The error message emitted by libmalloc changed in macOS 26. Update the
test to support both.
2025-08-19 10:49:23 -07:00
Jonas Devlieghere
d8208b0575
Revert "[lldb] Relax the error message in TestProcessCrashInfo.py" (#154197)
Reverts llvm/llvm-project#153653 because older versions of macOS do not
use the same prefix.
2025-08-18 20:53:12 +00:00
Jonas Devlieghere
4b94c08a57
[lldb] Relax the error message in TestProcessCrashInfo.py (#153653)
The error message has been updated in macOS 26. Relax the error message
to check the more generic "BUG IN CLIENT OF LIBMALLOC" rather than the
error message that comes after.
2025-08-18 14:01:41 -05:00
David Spickett
52f7cfb5ef [lldb][test] Remove a Windows xfail from TestThreadStates
This case is passing since https://github.com/llvm/llvm-project/pull/152020.
2025-08-12 10:48:46 +00:00
Matheus Izvekov
91cdd35008
[clang] Improve nested name specifier AST representation (#147835)
This is a major change on how we represent nested name qualifications in
the AST.

* The nested name specifier itself and how it's stored is changed. The
prefixes for types are handled within the type hierarchy, which makes
canonicalization for them super cheap, no memory allocation required.
Also translating a type into nested name specifier form becomes a no-op.
An identifier is stored as a DependentNameType. The nested name
specifier gains a lightweight handle class, to be used instead of
passing around pointers, which is similar to what is implemented for
TemplateName. There is still one free bit available, and this handle can
be used within a PointerUnion and PointerIntPair, which should keep
bit-packing aficionados happy.
* The ElaboratedType node is removed, all type nodes in which it could
previously apply to can now store the elaborated keyword and name
qualifier, tail allocating when present.
* TagTypes can now point to the exact declaration found when producing
these, as opposed to the previous situation of there only existing one
TagType per entity. This increases the amount of type sugar retained,
and can have several applications, for example in tracking module
ownership, and other tools which care about source file origins, such as
IWYU. These TagTypes are lazily allocated, in order to limit the
increase in AST size.

This patch offers a great performance benefit.

It greatly improves compilation time for
[stdexec](https://github.com/NVIDIA/stdexec). For one datapoint, for
`test_on2.cpp` in that project, which is the slowest compiling test,
this patch improves `-c` compilation time by about 7.2%, with the
`-fsyntax-only` improvement being at ~12%.

This has great results on compile-time-tracker as well:

![image](https://github.com/user-attachments/assets/700dce98-2cab-4aa8-97d1-b038c0bee831)

This patch also further enables other optimziations in the future, and
will reduce the performance impact of template specialization resugaring
when that lands.

It has some other miscelaneous drive-by fixes.

About the review: Yes the patch is huge, sorry about that. Part of the
reason is that I started by the nested name specifier part, before the
ElaboratedType part, but that had a huge performance downside, as
ElaboratedType is a big performance hog. I didn't have the steam to go
back and change the patch after the fact.

There is also a lot of internal API changes, and it made sense to remove
ElaboratedType in one go, versus removing it from one type at a time, as
that would present much more churn to the users. Also, the nested name
specifier having a different API avoids missing changes related to how
prefixes work now, which could make existing code compile but not work.

How to review: The important changes are all in
`clang/include/clang/AST` and `clang/lib/AST`, with also important
changes in `clang/lib/Sema/TreeTransform.h`.

The rest and bulk of the changes are mostly consequences of the changes
in API.

PS: TagType::getDecl is renamed to `getOriginalDecl` in this patch, just
for easier to rebasing. I plan to rename it back after this lands.

Fixes #136624
Fixes https://github.com/llvm/llvm-project/issues/43179
Fixes https://github.com/llvm/llvm-project/issues/68670
Fixes https://github.com/llvm/llvm-project/issues/92757
2025-08-09 05:06:53 -03:00
qxy11
7fb620a5cc
Fix a deadlock in ModuleList when starting a standalone lldb client/server (#148774)
Summary:
There was a deadlock was introduced by [PR
#146441](https://github.com/llvm/llvm-project/pull/146441) which changed
`CurrentThreadIsPrivateStateThread()` to
`CurrentThreadPosesAsPrivateStateThread()`. This change caused the
execution path in
[`ExecutionContextRef::SetTargetPtr()`](10b5558b61/lldb/source/Target/ExecutionContext.cpp (L513))
to now enter a code block that was previously skipped, triggering
[`GetSelectedFrame()`](10b5558b61/lldb/source/Target/ExecutionContext.cpp (L522))
which leads to a deadlock.

Thread 1 gets m_modules_mutex in
[`ModuleList::AppendImpl`](96148f9214/lldb/source/Core/ModuleList.cpp (L218)),
Thread 3 gets m_language_runtimes_mutex in
[`GetLanguageRuntime`](96148f9214/lldb/source/Target/Process.cpp (L1501)),
but then Thread 1 waits for m_language_runtimes_mutex in
[`GetLanguageRuntime`](96148f9214/lldb/source/Target/Process.cpp (L1501))
while Thread 3 waits for m_modules_mutex in
[`ScanForGNUstepObjCLibraryCandidate`](96148f9214/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp (L57)).

This fixes the deadlock by adding a scoped block around the mutex lock
before the call to the notifier, and moved the notifier call outside of
the mutex-guarded section. The notifier call
[`NotifyModuleAdded`](96148f9214/lldb/source/Target/Target.cpp (L1810))
should be thread-safe, since the module should be added to the
`ModuleList` before the mutex is released, and the notifier doesn't
modify the module list further, and the call is operates on local state
and the `Target` instance.

### Deadlocked Thread backtraces:
```
* thread #3, name = 'dbg.evt-handler', stop reason = signal SIGSTOP
  * frame #0: 0x00007f2f1e2973dc libc.so.6`futex_wait(private=0, expected=2, futex_word=0x0000563786bd5f40) at    futex-internal.h:146:13
   /*... a bunch of mutex related bt ... */    
   liblldb.so.21.0git`std::lock_guard<std::recursive_mutex>::lock_guard(this=0x00007f2f0f1927b0, __m=0x0000563786bd5f40) at std_mutex.h:229:19
    frame #8: 0x00007f2f27946eb7 liblldb.so.21.0git`ScanForGNUstepObjCLibraryCandidate(modules=0x0000563786bd5f28, TT=0x0000563786bd5eb8) at GNUstepObjCRuntime.cpp:60:41
    frame #9: 0x00007f2f27946c80 liblldb.so.21.0git`lldb_private::GNUstepObjCRuntime::CreateInstance(process=0x0000563785e1d360, language=eLanguageTypeObjC) at GNUstepObjCRuntime.cpp:87:8
    frame #10: 0x00007f2f2746fca5 liblldb.so.21.0git`lldb_private::LanguageRuntime::FindPlugin(process=0x0000563785e1d360, language=eLanguageTypeObjC) at LanguageRuntime.cpp:210:36
    frame #11: 0x00007f2f2742c9e3 liblldb.so.21.0git`lldb_private::Process::GetLanguageRuntime(this=0x0000563785e1d360, language=eLanguageTypeObjC) at Process.cpp:1516:9
    ...
    frame #21: 0x00007f2f2750b5cc liblldb.so.21.0git`lldb_private::Thread::GetSelectedFrame(this=0x0000563785e064d0, select_most_relevant=DoNoSelectMostRelevantFrame) at Thread.cpp:274:48
    frame #22: 0x00007f2f273f9957 liblldb.so.21.0git`lldb_private::ExecutionContextRef::SetTargetPtr(this=0x00007f2f0f193778, target=0x0000563786bd5be0, adopt_selected=true) at ExecutionContext.cpp:525:32
    frame #23: 0x00007f2f273f9714 liblldb.so.21.0git`lldb_private::ExecutionContextRef::ExecutionContextRef(this=0x00007f2f0f193778, target=0x0000563786bd5be0, adopt_selected=true) at ExecutionContext.cpp:413:3
    frame #24: 0x00007f2f270e80af liblldb.so.21.0git`lldb_private::Debugger::GetSelectedExecutionContext(this=0x0000563785d83bc0) at Debugger.cpp:1225:23
    frame #25: 0x00007f2f271bb7fd liblldb.so.21.0git`lldb_private::Statusline::Redraw(this=0x0000563785d83f30, update=true) at Statusline.cpp:136:41
    ...
* thread #1, name = 'lldb', stop reason = signal SIGSTOP
  * frame #0: 0x00007f2f1e2973dc libc.so.6`futex_wait(private=0, expected=2, futex_word=0x0000563785e1dd98) at futex-internal.h:146:13
   /*... a bunch of mutex related bt ... */    
   liblldb.so.21.0git`std::lock_guard<std::recursive_mutex>::lock_guard(this=0x00007ffe62be0488, __m=0x0000563785e1dd98) at std_mutex.h:229:19
    frame #8: 0x00007f2f2742c8d1 liblldb.so.21.0git`lldb_private::Process::GetLanguageRuntime(this=0x0000563785e1d360, language=eLanguageTypeC_plus_plus) at Process.cpp:1510:41
    frame #9: 0x00007f2f2743c46f liblldb.so.21.0git`lldb_private::Process::ModulesDidLoad(this=0x0000563785e1d360, module_list=0x00007ffe62be06a0) at Process.cpp:6082:36
    ...
    frame #13: 0x00007f2f2715cf03 liblldb.so.21.0git`lldb_private::ModuleList::AppendImpl(this=0x0000563786bd5f28, module_sp=ptr = 0x563785cec560, use_notifier=true) at ModuleList.cpp:246:19
    frame #14: 0x00007f2f2715cf4c liblldb.so.21.0git`lldb_private::ModuleList::Append(this=0x0000563786bd5f28, module_sp=ptr = 0x563785cec560, notify=true) at ModuleList.cpp:251:3
    ...
    frame #19: 0x00007f2f274349b3 liblldb.so.21.0git`lldb_private::Process::ConnectRemote(this=0x0000563785e1d360, remote_url=(Data = "connect://localhost:1234", Length = 24)) at Process.cpp:3250:9
    frame #20: 0x00007f2f27411e0e liblldb.so.21.0git`lldb_private::Platform::DoConnectProcess(this=0x0000563785c59990, connect_url=(Data = "connect://localhost:1234", Length = 24), plugin_name=(Data = "gdb-remote", Length = 10), debugger=0x0000563785d83bc0, stream=0x00007ffe62be3128, target=0x0000563786bd5be0, error=0x00007ffe62be1ca0) at Platform.cpp:1926:23
```

## Test Plan:
Built a hello world a.out
Run server in one terminal:
```
~/llvm/build/Debug/bin/lldb-server g :1234 a.out
```
Run client in another terminal
```
~/llvm/build/Debug/bin/lldb -o "gdb-remote 1234" -o "b hello.cc:3"
```

Before:
Client hangs indefinitely
```
~/llvm/build/Debug/bin/lldb -o "gdb-remote 1234" -o "b main"
(lldb) gdb-remote 1234

^C^C
```

After:
```
~/llvm/build/Debug/bin/lldb -o "gdb-remote 1234" -o "b hello.cc:3"
(lldb) gdb-remote 1234
Process 837068 stopped
* thread #1, name = 'a.out', stop reason = signal SIGSTOP
    frame #0: 0x00007ffff7fe4a60
ld-linux-x86-64.so.2`_start:
->  0x7ffff7fe4a60 <+0>: movq   %rsp, %rdi
    0x7ffff7fe4a63 <+3>: callq  0x7ffff7fe5780 ; _dl_start at rtld.c:522:1

ld-linux-x86-64.so.2`_dl_start_user:
    0x7ffff7fe4a68 <+0>: movq   %rax, %r12
    0x7ffff7fe4a6b <+3>: movl   0x18067(%rip), %eax ; _dl_skip_args
(lldb) b hello.cc:3
Breakpoint 1: where = a.out`main + 15 at hello.cc:4:13, address = 0x00005555555551bf
(lldb) c
Process 837068 resuming
Process 837068 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
    frame #0: 0x00005555555551bf a.out`main at hello.cc:4:13
   1   	#include <iostream>
   2
   3   	int main() {
-> 4   	  std::cout << "Hello World" << std::endl;
   5   	  return 0;
   6   	}
```
2025-08-04 08:43:49 -07:00
Michael Buch
779868de69 [lldb][test] Skip tail_call_frames tests on older Clang versions
These have been un-XFAILed in
`ebe6eba62580592af7065a36b22d929c15291e9a`, but require following Clang
fix: https://github.com/llvm/llvm-project/pull/150022. So skip older
compilers.
2025-08-03 00:01:19 +01:00
Igor Kudrin
55c2b273ea
[lldb] Ensure that TestMemoryCache.py reads allocated memory (#151635)
The test reads 400 bytes of memory above the local variable. If the
stack is shallow, this can reach non-allocated space, resulting in a
test failure. The patch fixes the issue by reserving enough space in
the upper stack frame.
2025-08-01 12:51:59 -07:00
Michael Buch
ebe6eba625 [lldb][test] Un-XFAIL tail_call_frames tests on Linux arm/arm64
These have been XPASSing after
https://github.com/llvm/llvm-project/pull/150022
2025-08-01 11:19:53 +01:00
Dave Lee
68b9bb5e9b
[lldb] Add stop_description Python property to SBThread (#151568)
Add `stop_description` as a Python convenience property to `SBThread`.
2025-07-31 13:10:04 -07:00
Jonas Devlieghere
f62370290a
[lldb] Implement RegisterContextWasm (#151056)
This PR implements a register context for Wasm, which uses virtual
registers to resolve Wasm local, globals and stack values. The registers
are used to implement support for `DW_OP_WASM_location` in the DWARF
expression evaluator (#151010). This also adds a more comprehensive
test, showing that we can use this to show local variables.
2025-07-30 19:51:09 -07:00
Igor Kudrin
e4c0f30030
[lldb] Fix updating persistent variables without JIT (#149642)
This patch fixes updating persistent variables when memory cannot be
allocated in an inferior process:
```
> lldb -c test.core
(lldb) expr int $i = 5
(lldb) expr $i = 55
(int) $0 = 55
(lldb) expr $i
(int) $i = 5
```

With this patch, the last command prints:
```
(int) $i = 55
```

The issue was introduced in #145599.
2025-07-30 12:54:15 -07:00
Jonas Devlieghere
a28e7f1aad
[lldb] Add WebAssembly Process Plugin (#150143)
Extend support in LLDB for WebAssembly. This PR adds a new Process
plugin (ProcessWasm) that extends ProcessGDBRemote for WebAssembly
targets. It adds support for WebAssembly's memory model with separate
address spaces, and the ability to fetch the call stack from the
WebAssembly runtime.

I have tested this change with the WebAssembly Micro Runtime (WAMR,
https://github.com/bytecodealliance/wasm-micro-runtime) which implements
a GDB debug stub and supports the qWasmCallStack packet.

```
(lldb) process connect --plugin wasm connect://localhost:4567
Process 1 stopped
* thread #1, name = 'nobody', stop reason = trace
    frame #0: 0x40000000000001ad
wasm32_args.wasm`main:
->  0x40000000000001ad <+3>:  global.get 0
    0x40000000000001b3 <+9>:  i32.const 16
    0x40000000000001b5 <+11>: i32.sub
    0x40000000000001b6 <+12>: local.set 0
(lldb) b add
Breakpoint 1: where = wasm32_args.wasm`add + 28 at test.c:4:12, address = 0x400000000000019c
(lldb) c
Process 1 resuming
Process 1 stopped
* thread #1, name = 'nobody', stop reason = breakpoint 1.1
    frame #0: 0x400000000000019c wasm32_args.wasm`add(a=<unavailable>, b=<unavailable>) at test.c:4:12
   1    int
   2    add(int a, int b)
   3    {
-> 4        return a + b;
   5    }
   6
   7    int
(lldb) bt
* thread #1, name = 'nobody', stop reason = breakpoint 1.1
  * frame #0: 0x400000000000019c wasm32_args.wasm`add(a=<unavailable>, b=<unavailable>) at test.c:4:12
    frame #1: 0x40000000000001e5 wasm32_args.wasm`main at test.c:12:12
    frame #2: 0x40000000000001fe wasm32_args.wasm
```

This PR is based on an unmerged patch from Paolo Severini:
https://reviews.llvm.org/D78801. I intentionally stuck to the
foundations to keep this PR small. I have more PRs in the pipeline to
support the other features/packets.

My motivation for supporting Wasm is to support debugging Swift compiled
to WebAssembly:
https://www.swift.org/documentation/articles/wasm-getting-started.html
2025-07-29 10:07:13 -07:00
jimingham
4c8e79f815
Switch the ScriptedBreakpointResolver over to the ScriptedInterface form (#150720)
This is NFC, I'm modernizing the interface before I add to it in a
subsequent commit.
2025-07-28 15:11:22 -07:00
satyanarayana reddy janga
ea480cc665
[lldb] support ieee_single and ieee_double gdbtypes for registers (#150268)
Some gdb remote servers send target.xml that contains 
```
<reg name='ft0' bitsize='32' type='ieee_single' dwarf_regnum='32'/>
  <reg name='ft1' bitsize='32' type='ieee_single' dwarf_regnum='33'/>
  <reg name='ft2' bitsize='32' type='ieee_single' dwarf_regnum='34'/>
  <reg name='ft3' bitsize='32' type='ieee_single' dwarf_regnum='35'/>
  <reg name='ft4' bitsize='32' type='ieee_single' dwarf_regnum='36'/>
  <reg name='ft5' bitsize='32' type='ieee_single' dwarf_regnum='37'/>
  <reg name='ft6' bitsize='32' type='ieee_single' dwarf_regnum='38'/>
  <reg name='ft7' bitsize='32' type='ieee_single' dwarf_regnum='39'/>
```

it seems like a valid and supported type in gdb. 
from gdb16.3/gdb/target_descriptions.c (could not find a way to link
it).
```
case TDESC_TYPE_IEEE_SINGLE:
	  m_type = init_float_type (alloc, -1, "builtin_type_ieee_single",
				    floatformats_ieee_single);
	  return;

case TDESC_TYPE_IEEE_DOUBLE:
	  m_type = init_float_type (alloc, -1, "builtin_type_ieee_double",
				    floatformats_ieee_double);
	  return;
```	

### Testplan

updated unittest to test this. 


Reviewers: @clayborg , @jeffreytan81 , @Jlalond
2025-07-28 13:09:41 -07:00