* Correctly return the result when used from the console, so that
`DiagnosticsRendering` could use it to output the error.
* Add location pointer to `DILDiagnosticError` internal formatting to
show diagnostics when called from the API.
This patch is motivated by
https://github.com/llvm/llvm-project/pull/189943, where we would like to
print the "these module scripts weren't loaded" warning for *all*
modules batched together. I.e., we want to print the warning *after* all
the script loading attempts, not from within each attempt.
To do so we want to hoist the `ReportWarning` calls in
`Module::LoadScriptingResourceInTarget` out into the callsites. But if
we do that, the callers have to remember to print the warnings. To avoid
this, we redirect all callsites to use
`ModuleList::LoadScriptingResourceInTarget`, which will be responsible
for printing the warnings.
To avoid future accidental uses of
`Module::LoadScriptingResourceInTarget` I moved the API into
`ModuleList` and made it `private`.
A kernel developer noticed that I missed a call to index the local
filesystem in one of our codepaths, and had a use case that depended on
that working.
rdar://173814556
Many tests have ad hoc forms of the launch & break steps done by
`lldbutil.run_to_source_breakpoint`. This changes some of those tests to
use `run_to_source_breakpoint` instead.
Assisted-by: claude
This test technically does not require libc++. The test binary mimics
libc++'s namespace layout to trigger some frame hiding logic in lldb,
but it does not require libc++ to function.
This is explicitly marked as a libc++ test and functionally tests the
formatter for a vector of enums. I put it in the generic directory
because there's no reason this couldn't work for other c++ stdlibs.
Additionally, this should be using the custom libc++ like the other
tests.
In some environments like swiftlang, the `''` causes the command used to
drain the init sequence of the ConPTY to fail. Replacing with a `cls`
invocation removes the need for quotation marks and works just as well.
For whatever reason we ended up with register/register but the first
register just had the second register folder in it.
Move the files up one level so we have register/<test files>.
Fixes#165413. Where a build failure was reported:
```
/b/s/w/ir/x/w/llvm-llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp:1182:9: error: unknown type name 'user_sve_header'; did you mean 'sve::user_sve_header'?
1182 | user_sve_header *header =
| ^~~~~~~~~~~~~~~
| sve::user_sve_header
```
To fix this, add sve:: as we do for all other uses of this.
This is LLDB's copy of a structure that Linux also defines. I think the
build worked on some machines because that version ended up being
included, but with a more isolated build, it may not.
We have our own definition of it so we can be sure what we're using in
case Linux extends it later.
Tests with custom a.out targets in their Makefile (i.e.
`TestBSDArchives.py`) bypass the standard Makefile.rules linking step
where `CODESIGN` is applied. This leaves the binary unsigned, causing
the process to get kill it on remote darwin devices.
This adds a codesigning step to the all target in Makefile.rules that
signs both $(EXE) and a.out if they exist. This ensures all test
binaries are signed regardless of how they were built.
rdar://173840592
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
This PR is the tests for #138717. I have split it from implementation as
there is a lot of code, and the two don't really overlap. The tests are
checking what a user will see in LLDB, and only indirectly what happens
in lldb-server.
There are two types of tests, the first is register access tests. These
start in a given mode, where a mode is a combination of the streaming
mode on or off, ZA on or off, and a vector length.
For register access tests I have used two states:
* Streaming mode, ZA on, default vector length
* Non-streaming mode, ZA off, default vector length
(changing mode and vector length is tested in existing SVE+SME tests and
the expression tests I'm adding in this same PR)
The test program:
* Sets up the requested mode.
* Allocates a bunch of buffers for LLDB to write expected register
values to.
* Sets initial register values.
Then LLDB looks for those expected values. Assuming they are present, it
then writes a new set of values to the registers, and to the buffers
within the program. The program is then stepped, which runs an
in-process function to check that it now sees those register values. If
that function fails, we have a bug. If it does not, LLDB then checks for
the same values.
This process repeats for several registers. Hence the repeated calls to
check_register_values in the test program.
In this way we make sure that LLDB sends the correct values to ptrace by
validating them in process. Also that LLDB does not write other
registers in the process of writing one register. Which happened to me
several times during development.
The buffer writes are done with memory writes not expression evaluation
becuase at this stage we cannot trust that expressions work (the
expression tests will later prove that they do).
The second type of tests are expression state restoration tests. For
each combination of states we check that we can restore to a given state
if an expression takes us into the other state. This includes between
the same state, and adds an extra vector length to check expanding and
shrinking SVE buffers. This produces roughly 64 tests.
I have written them all as one test case in a loop because these take a
long time (~20 minutes on an FVP) and you almost always want it to fail
fast. When tracing is enabled you'll see the current states logged.
It's possible that we could skip some of these tests as being very
unlikely to ever happen, but in the spirit of
"There are Only Four Billion Floats–So Test Them All!" I think it is
simpler to enumerate every possible state change.
I have not added a test for executing an expression incompatible with
the current mode because this leads to SIGILL, which I know we already
handle. At this time LLDB makes no effort to make the expression
compatible with the current mode either.
This is the implementation part of #138717, tests and documentation will
be in a separate PR.
SME only systems have SME but not SVE. Previously we assumed that you
would either have SVE, SVE+SME, or neither. On an SME only system, the
SVE register state exists only in streaming mode. SVE instructions may
be used, but only in streaming mode. The Linux kernel will report that
such a processor has SME features but no SVE features.
This means that the non-streaming SVE ptrace register set is
inaccessible (with one exception mentioned below). So the main change
here is around the management of FP registers.
* In non-streaming mode, FP registers must be accessed via the FP
register set. Not the non-streaming SVE register set.
* In streaming mode, FP registers are a subset of the streaming SVE
registers, accessed via the streaming SVE register set.
The one exception the kernel allows is:
> On systems that do not support SVE it is permitted to use SETREGSET to
write SVE_PT_REGS_FPSIMD formatted data via NT_ARM_SVE, in this case the
vector length should be specified as 0. This allows streaming mode to be
disabled on systems with SME but not SVE.
https://docs.kernel.org/arch/arm64/sve.html
This is how we are able to restore to a non-streaming state when an
expression leaves us in streaming mode.
The major changes to LLDB are:
* If we receive only SVG in the expedited registers, we now assume it's
an SME only system and therefore VG == SVG.
* A new state SVEState::StreamingFPSIMD is added to mark the mode where
we are in FPSIMD mode on an SME only system (as opposed to the FPSIMD
state of an SVE or SVE+SME system).
* CalculateFprOffset now returns different results depending on whether
we have only SIMD or we have streaming SVE. In the latter case, the
stored register offsets are relative to the SVE registers, but actual
accesses need to be relative to the ptrace FP register set.
* In WriteAllRegisters, if we have an FP set to restore on an SME only
system we assume we must have been in non-streaming mode at the time of
the save. So we restore it using the previously mentioned non-streaming
SVE write.
* GetSVERegSet and ConfigureRegisterContext were updated to handle the
new StreamingFPSIMDOnly state.
The only difference between them is that OptionalBool's third state
is "unknown" and LazyBool's is "calculate". We don't need to tell
the difference in a single context, so I've made a new eLazyBoolDontKnow
which is an alias of eLazyBoolCalculate.
This patch changes the `Platform::LocateXXX` to return a map from
`FileSpec` to `LoadScriptFromSymFile` enum.
This is needed for https://github.com/llvm/llvm-project/pull/188722,
where I intend to set `LoadScriptFromSymFile` per-module.
By default the `Platform::LocateXXX` set the value to whatever the
target's current `target.load-script-from-symbol-file` is set to. In
https://github.com/llvm/llvm-project/pull/188722 we'll allow overriding
this per-target setting on a per-module basis.
Drive-by:
* Added logging when we fail to load a script.
In preparation for updating DIL to handle assignments, this adds a
member variable to the DIL Interpreter indicating whether or not
updating program variables is allowed. For invocations from the LLDB
command prompt (through "frame variable") we want to allow it, but from
other places we might not. Therefore we also add new StackFrame
ExpressionPathOption, eExpressionPathOptionsAllowVarUpdates, which we
add to calls from CommandObjectFrame, and which is checked in
GetValueForVariableExpressionPath. Finally, we also add a parameter,
can_update_vars, with a default value of true, to
ValueObject::SetValueFromInteger, as that will be the main function used
to by assignment in DIL.
I've been tracking sporadic timeouts waiting for a file to appear on
macOS buildbots (and occasionally local development environments). I
believe I've tracked it down to a regression in process launch
performance in macOS.
What I noticed is that running multiple test suites simultaneously
almost always triggered these failures and that the tests were always
waiting on files created by the inferior. Increasing this timeout no
longer triggers the failures on my loaded machine locally.
This timeout moves from about 16 seconds of total wait time to about 127
seconds of total wait time. This may feel a bit extreme, but this is a
performance issue. While I was here, I cleaned up logging code I was
using to investigate the test failures.
rdar://172122213
We already log the import attempt. This patch logs the failure to load
the script since otherwise the log may be misleading. Didn't think it
was worth adding a test-case for this.
Fixes an issue where attaching by program would fail if the program name
was a partial name (e.g. "foobar" instead of "/path/to/foobar").
We failed to create the target which caused the attach to fail. Now we
fallback to the dummy target and update to the real target after the
attach completes.
Here is an example launch configuration that fail:
```
{
"type": "lldb-dap",
"name": "Attach (wait)",
"request": "attach",
"program": "foobar",
"waitFor": true
},
```
By turning SetMemoryTagged into a builder method (returns a reference to
self). Then only using that in the tests that need to change the default
of "don't know".
This patch introduces `PlatformContext.getFullLibName` which returns the
full dylib name for any platform based on the base name of the dylib.
Example:
```
# Windows
PlatformContext.getFullLibName("Foo") -> "Foo.dll"
# Linux
PlatformContext.getFullLibName("Foo") -> "libFoo.so"
```
Nothing passes anything but the default value here. Code that wants to
set it is starting with a default constructed info, and filling in the
fields one by one (the gdb-remote client for example).
Meaning a method on an object, which returns a reference to self.
I am doing this because it was pointed out to me that MemoryRegionInfo
has lots of construction paramaters, and most of the time, we want the
default value for most of the things.
So now we can do:
MemoryRegionInfo(...); // Shadow stack is "don't know".
MemoryRegionInfo(...).SetIsShadowStack(eNo) // Shadow stack is "no".
Which removes one parameter from every use of the constructor.
Along the way I realised that the shadow stack "ss" flag is only tested
by the Guarded Control Stack tests, which only run on specific Arm
hardware. I've added a new "ss" test to LinuxProcMapsTest, which will
run on any system.
This plugin creates types based on information from target XML, which is
parsed only once per session. It has internal logic to reuse created
types, but the plugin itself was being remade every time a type was
requested.
SetPrivateRunLockToRunning incorrectly delegated to
SetPrivateRunLockToStopped instead of SetPrivateRunLockToRunning,
causing the private run lock to never transition to the running state on
process resume.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When debugging a remote Darwin device (iOS, macOS, etc), lldb needs to
find a local copy of all the system libraries (the system's shared
cache) so we don't need to read them over gdb-remote serial protocol at
the start of every debug session.
Xcode etc normally creates these expanded shared caches in
~/Library/Developer/Xcode/<OS> DeviceSupport/<OS VER> (<OS
BUILD>)/Symbols
So when lldb sees a file like /usr/lib/libSystem.B.dylib, it may find a
copy at in
~/L/D/Xcode/iOS DeviceSupport/26.2
(23B87)/Symbols/usr/lib/libSystem.B.dylib
There may be multiple expanded shared caches in these DeviceSupport
directories, so we try to parse the "os version" and "os build" out of
the filepath name, and look in a directory that matches the target
device's OS Version as an optimization, to avoid opening the given file
in other DeviceSupport directories.
There is a new layout where the cpu arch exists as a subdirectory under
the "<OS VER> (<OS BUILD>)" directory. e.g.
~/L/D/Xcode/iOS DeviceSupport/26.2 (23B87)/arm64e/Symbols/...
and it is possible that we could have multiple arch names for a given
build -- for instance, an Apple Watch that can have either arm64e or
arm64_32 shared caches.
The existing code also had a very simplistic way of parsing "<OS VER>
(<OS BUILD>)" from the directory name that hasn't been kept up to date
with how the directory names have changed over the years. We have some
like "Watch4,2 10.0 (21R329)" or "10.0 (21R329) universal" which may not
parse with the older parser.
This PR looks for target arch subdirs under the given directories,
passes the os version/build version string separately because it may not
be the final component in the directory name any more, and updates the
directory parser that finds the version and build numbers.
rdar://171821410
Updates the lldb python test suite to ensure we call dumpSessionInfo()
in the test result's stopTest() method. This will ensure that we get the
session info dumped for all tests, even those that don't have an
explicit call to dumpSessionInfo() in the test case.
Additionally, I updated the lldb-dap test case to mark the '-dap.log' as
a log file, which will be recorded in the test output on failure.
Here is an example test run with a failure:
```
PASS: LLDB (build/bin/clang-arm64) :: test_step (TestDAP_step.TestDAP_step)
FAIL: LLDB (build/bin/clang-arm64) :: test_step_over_inlined_function (TestDAP_step.TestDAP_step)
Log Files:
- build/lldb-test-build.noindex/tools/lldb-dap/step/TestDAP_step/Failure.log
- build/lldb-test-build.noindex/tools/lldb-dap/step/TestDAP_step/Failure-dap.log
======================================================================
FAIL: test_step_over_inlined_function (TestDAP_step.TestDAP_step)
Test stepping over when the program counter is in another file.
----------------------------------------------------------------------
Traceback (most recent call last):
File "llvm-project/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py", line 113, in test_step_over_inlined_function
self.assertFalse(
AssertionError: True is not false : expect path ending with 'main.cpp'.
Config=arm64-build/bin/clang
----------------------------------------------------------------------
Ran 2 tests in 4.849s
```
In `internalConsole` mode (especially in VSCode), lldb-dap should not
use the ConPTY to read the process' output. This is because the
internalConsole is not a real terminal, there is no reason to use
terminal emulation, which will add arbitrary line returns to the output.
Instead, this patch introduces the `eLaunchFlagUsePipes` flag in
ProcessLaunchInfo which tells ProcessLaunchWindows to use regular pipes
instead of a ConPTY to get the stdin and stdout of the debuggee.
The result is that output which is supposed to be on a single line is
properly rendered.
---
The following example is when debugging a program through lldb-dap on
Windows. The program prints the numbers 0 through 999 on a single line.
# Before
<img width="2214" height="672" alt="Screenshot 2026-03-13 at 17 07 35"
src="https://github.com/user-attachments/assets/26292d11-2288-46ee-a6d2-0b66bfa41288"
/>
The line is split if it's longer than 80 characters (default terminal
size).
# After
<img width="2215" height="689" alt="Screenshot 2026-03-13 at 17 12 39"
src="https://github.com/user-attachments/assets/c9cad9af-b1ce-4c7b-91d5-f684e48e64ca"
/>
The line is correctly printed as a single line.
rdar://172491166
While here:
* Move the constructor to the public section. Almost all ThreadPlan
classes have public constructors.
* Use `std::make_shared()`. It is modern and more efficient.
`lldb-private-types.h` includes `lldb-private.h`, which in turn includes
`lldb-private-types.h`. Because of that, `lldb-public.h` included by
`lldb-private.h` after `lldb-private-types.h` is not actually included.
The practical consequence of this is that types defined in
`lldb-public-types.h` (for example, `addr_t` needed downstream) are not
available in `lldb-private-types.h`.
Fix this by "including what you use", which is `lldb-types.h`.
Also deserialize them back again on reading.
The implementation is based on the existing implementation of `#pragma
weak` serialization.
Fixes issue #186742.
---------
Co-authored-by: Chuanqi Xu <yedeng.yd@linux.alibaba.com>
Part 4. This converts all the remaining simple uses (the ones that ended
with a newline).
What remains in tree are the outliers that expect multiple ending
newlines, or are building a message in pieces.
- it is always passed as zero
- a lot of plugins aren't using it correctly
- the data extractor class already has the capability to look at a
subset of bytes
Add extra guards in case a call to function fails. For example, the
result of `ReadMemory()` cannot be trusted when `error.Fail()` is true,
and this change ensures the code executes properly according to the
value of the error.
Signed-off-by: Minsoo Choo <minsoochoo0122@proton.me>
After this change, Address::SetSection() had only one use left (in a
unit test) and was removed. Address::ClearSection() had no uses, now
also removed. (It is unlikely that someone needs to change the section
without simultaneously changing the section offset, and for that we have
a constructor.)