Letting Editline refresh itself is more robust and ensures that the
current text is redraw if it was accidentally cleared. In that scenario
MoveCursor would only fix up the cursor position.
As a preliminary to making DIL the default implementation for
'frame var', ran check-lldb forcing 'frame var' to always use DIL,
and discovered a few failing tests. This fixes most of them. The only
remaining failing test is TestDAP_evaluate.py, which now passes
a test case that the test says should fail (still investigating this).
Changes in this PR:
- Sets correct VariableSP, as well as returning ValueObjectSP (needed
for several watchpoint tests).
- Updates error messages, when looking up members, to match what the
rest of LLDB expects. Also update appropriate DIL tests to expect the
updated error messages.
- Updates DIL parser to look for and accept "(anonymous namespace)::" at
the front of a variable name.
This PR ensures we correctly restore the cursor column after resizing
the statusline. To ensure we have space for the statusline, we have to
emit a newline to move up everything on screen. The newline causes the
cursor to move to the start of the next line, which needs to be undone.
Normally, we would use escape codes to save & restore the cursor
position, but that doesn't work here, as the cursor position may have
(purposely) changed. Instead, we move the cursor up one line using an
escape code, but we weren't restoring the column.
Interestingly, Editline was able to recover from this issue through the
LineInfo struct which contains the buffer and the cursor location, which
allows us to compute the column. This PR addresses the bug by having
Editline "refresh" the cursor position.
Fixes#134064
lldb-server had limited support for single-stepping through the lr/sc
atomic sequence. This patch enhances that support for all possible
atomic sequences.
The previous version contained an incorrect regex pattern in the test,
causing the riscv-specific test to run on other platforms. This reland
fixes the regex (see lldb/test/API/riscv/step/TestSoftwareStep.py)
The "process metadata" LC_NOTE allows for thread IDs to be specified in
a Mach-O corefile. This extends the JSON recognzied in that LC_NOTE to
allow for additional registers to be supplied on a per-thread basis.
The registers included in a Mach-O corefile LC_THREAD load command can
only be one of the register flavors that the kernel (xnu) defines in
<mach/arm/thread_status.h> for arm64 -- the general purpose registers,
floating point registers, exception registers.
JTAG style corefile producers may have access to many additional
registers beyond these that EL0 programs typically use, for instance
TCR_EL1 on AArch64, and people developing low level code need access to
these registers. This patch defines a format for including these
registers for any thread.
The JSON in "process metadata" is a dictionary that must have a
`threads` key. The value is an array of entries, one per LC_THREAD in
the Mach-O corefile. The number of entries must match the LC_THREADs so
they can be correctly associated.
Each thread's dictionary must have two keys, `sets`, and `registers`.
`sets` is an array of register set names. If a register set name matches
one from the LC_THREAD core registers, any registers that are defined
will be added to that register set. e.g. metadata can add a register to
the "General Purpose Registers" set that lldb shows users.
`registers` is an array of dictionaries, one per register. Each register
must have the keys `name`, `value`, `bitsize`, and `set`. It may provide
additional keys like `alt-name`, that
`DynamicRegisterInfo::SetRegisterInfo` recognizes.
This `sets` + `registers` formatting is the same that is used by the
`target.process.python-os-plugin-path` script interface uses, both are
parsed by `DynamicRegisterInfo`. The one addition is that in this
LC_NOTE metadata, each register must also have a `value` field, with the
value provided in big-endian base 10, as usual with JSON.
In RegisterContextUnifiedCore, I combine the register sets & registers
from the LC_THREAD for a specific thread, and the metadata sets &
registers for that thread from the LC_NOTE. Even if no LC_NOTE is
present, this class ingests the LC_THREAD register contexts and
reformats it to its internal stores before returning itself as the
RegisterContex, instead of shortcutting and returning the core's native
RegisterContext. I could have gone either way with that, but in the end
I decided if the code is correct, we should live on it always.
I added a test where we process save-core to create a userland corefile,
then use a utility "add-lcnote" to strip the existing "process metadata"
LC_NOTE that lldb put in it, and adds a new one from a JSON string.
rdar://74358787
---------
Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
If a server does not support allocating memory in an inferior process or
when debugging a core file, evaluating an expression in the context of a
value object results in an error:
```
error: <lldb wrapper prefix>:43:1: use of undeclared identifier '$__lldb_class'
43 | $__lldb_class::$__lldb_expr(void *$__lldb_arg)
| ^
```
Such expressions require a live address to be stored in the value
object. However, `EntityResultVariable::Dematerialize()` only sets
`ret->m_live_sp` if JIT is available, even if the address points to the
process memory and no custom allocations were made. Similarly,
`EntityPersistentVariable::Dematerialize()` tries to deallocate memory
based on the same check, resulting in an error if the memory was not
previously allocated in `EntityPersistentVariable::Materialize()`.
As an unintended bonus, the patch also fixes a FIXME case in
`TestCxxChar8_t.py`.
Add a class property for the version string. This allows you to use
access the version string through `lldb.SBDebugger.version` instead of
having to call `lldb.SBDebugger.GetVersionString()`.
This updates the DIL implementation to handle smart pointers (accessing
field members and dereferencing) in the same way the current 'frame
variable' implementation does. It also adds tests for handling smart
pointers, as well as some additional DIL tests.
.. from the guts of GDBRemoteCommunication to ~top level.
This is motivated by #131519 and by the fact that's impossible to guess
whether the author of a symlink intended it to be a "convenience
shortcut" -- meaning it should be resolved before looking for related
files; or an "implementation detail" -- meaning the related files should
be located near the symlink itself.
This debate is particularly ridiculous when it comes to lldb-server
running in platform mode, because it also functions as a debug server,
so what we really just need to do is to pass /proc/self/exe in a
platform-independent manner.
Moving the location logic higher up achieves that as lldb-platform (on
non-macos) can pass `HostInfo::GetProgramFileSpec`, while liblldb can
use the existing complex logic (which only worked on liblldb anyway as
lldb-platform doesn't have a lldb_private::Platform instance).
Another benefit of this patch is a reduction in dependency from
GDBRemoteCommunication to the rest of liblldb (achieved by avoiding the
Platform dependency).
It was assuming that for any location M.N, N was always less than the
number of breakpoint locations. But if you rebuild the target and rerun
multiple times, when the section backing one of the locations is no
longer valid, we remove the location, but we don't reuse the ID. So you
can have a breakpoint that only has location 1.3. The num_locations
check would say that was an invalid location.
…ess" (#144810)
This relands commit e0933ab5ae4856c4aa188a5ea16716b3a8d0840b. The
original commit was causing the test TestCreateAfterAttach.py to fail on
ARM Ubuntu bots. It's possible that this could've been happening because
the test for wait-attach progress reporting is waiting on a process
named "a.out" which could be too generic as multiple other tests (when
run in parallel on the bots) could also be using processes named
"a.out". This commit changes the wait-attach progress report test to
wait on a unique process name.
Original PR description:
This commit adds a progress report when wait-attaching to a process as
well as a test for this.
Original PR link: https://github.com/llvm/llvm-project/pull/144768
The
[protocol](https://microsoft.github.io/debug-adapter-protocol//specification.html#Types_Source)
expects that `sourceReference` be less than `(2^31)-1`, but we currently
represent memory address as source reference, this can be truncated
either when sending through json or by the client. Instead, generate new
source references based on the memory address.
Make the `ResolveSource` function return an optional source.
### Summary
Currently, if the setting `interpreter.save-transcript` is enabled,
whenever we call "statistics dump", it'll default to reporting a huge
list of transcripts which can be a bit noisy. This is because the
current check `GetIncludeTranscript` returns `!GetSummaryOnly()` by
default if no specific transcript-setting option is given in the
statistics dump command (ie. `statistics dump --transcripts=false` or
`statistics dump --transcripts=true`). Then when
`interpreter.save-transcript` is enabled, this saves a list of
transcripts, and the transcript list ends up getting logged by default.
These changes default the option to log transcripts in the `statistics
dump` command to "false". This can still be enabled via the
`--transcripts` option if users want to see a transcript. Since
`interpreter.save-transcript` is false by default, the main delta is
that if `interpreter.save-transcript` is true and summary mode is false,
we now disable saving the transcript.
This also adds a warning to 'statistics dump --transcript=true' when
interpreter.save-transcript is disabled, which should help users
understand
why transcript data is empty.
### Testing
#### Manual testing
Tested with `settings set interpreter.save-transcript true` enabled at
startup on a toy hello-world program:
```
(lldb) settings set interpreter.save-transcript true
(lldb) target create "/home/qxy11/hello-world/a.out"
Current executable set to '/home/qxy11/hello-world/a.out' (x86_64).
(lldb) statistics dump
{
/* no transcript */
}
(lldb) statistics dump --transcript=true
{
"transcript": [
{
"command": "statistics dump",
"commandArguments": "",
"commandName": "statistics dump",
"durationInSeconds": 0.0019650000000000002,
"error": "",
"output": "{...
},
{
"command": "statistics dump --transcript=true",
"commandArguments": "--transcript=true",
"commandName": "statistics dump",
"timestampInEpochSeconds": 1750720021
}
]
}
```
Without `settings set interpreter.save-transcript true`:
```
(lldb) target create "/home/qxy11/hello-world/a.out"
Current executable set to '/home/qxy11/hello-world/a.out' (x86_64).
(lldb) statistics dump
{
/* no transcript */
}
(lldb) statistics dump --transcript=true
{
/* no transcript */
}
warning: transcript requested but none was saved. Enable with 'settings set interpreter.save-transcript true'
```
#### Unit tests
Changed unit tests to account for new expected default behavior to
`false`, and added a couple new tests around expected behavior with
`--transcript=true`.
```
lldb-dotest -p TestStats ~/llvm-sand/external/llvm-project/lldb/test/API/commands/statistics/basic/
```
Desugar any potential references/typedefs before checking
`isStdTemplate`. Previously, the typename might've been:
```
const std::unordered_map<...> &
```
for references. This patch gets the pointee type before grabbing the
canonical type. `GetNonReferenceType` will unwrap typedefs too, so we
should always end up with a non-reference before we get to
`GetCanonicalType`.
https://github.com/llvm/llvm-project/issues/145847
# Benefit
This patch fixes:
1. After `platform select ios-simulator`, `platform process list` will
now print processes which are running in the iOS simulator. Previously,
no process will be listed.
2. After `platform select ios-simulator`, `platform attach --name
<name>` will succeed. Previously, it will error out saying no process is
found.
# Several bugs that is being fixed
1. During the process listing, add `aarch64` to the list of CPU types
for which iOS simulators are checked for.
2. Given a candidate process, when checking for simulators, the original
code will find the desired environment variable (`SIMULATOR_UDID`) and
set the OS to iOS, but then the immediate next environment variable will
set it back to macOS.
3. For processes running on simulator, set the triple's `Environment` to
`Simulator`, so that such processes can pass the filtering [in this
line](https://fburl.com/8nivnrjx). The original code leave it as the
default `UnknownEnvironment`.
# Manual test
**With this patch:**
```
royshi-mac-home ~/public_llvm/build % bin/lldb
(lldb) platform select ios-simulator
(lldb) platform process list
240 matching processes were found on "ios-simulator"
PID PARENT USER TRIPLE NAME
====== ====== ========== ============================== ============================
40511 28844 royshi arm64-apple-ios-simulator FocusPlayground // my toy iOS app running on simulator
... // omit
28844 1 royshi arm64-apple-ios-simulator launchd_sim
(lldb) process attach --name FocusPlayground
Process 40511 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x0000000104e3cb70 libsystem_kernel.dylib`mach_msg2_trap + 8
libsystem_kernel.dylib`mach_msg2_trap:
-> 0x104e3cb70 <+8>: ret
... // omit
```
**Without this patch:**
```
$ bin/lldb
(lldb) platform select ios-simulator
(lldb) platform process list
error: no processes were found on the "ios-simulator" platform
(lldb) process attach --name FocusPlayground
error: attach failed: could not find a process named FocusPlayground
```
# Unittest
See PR.
```
Traceback (most recent call last):
File "/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/dotest.py", line 8, in <module>
lldbsuite.test.run_suite()
File "/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/packages/Python/lldbsuite/test/dotest.py", line 1064, in run_suite
visit("Test", dirpath, filenames)
File "/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/packages/Python/lldbsuite/test/dotest.py", line 706, in visit
visit_file(dir, name)
File "/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/packages/Python/lldbsuite/test/dotest.py", line 649, in visit_file
module = __import__(base)
^^^^^^^^^^^^^^^^
File "/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py", line 14, in <module>
class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
File "/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py", line 29, in TestDAP_runInTerminal
@skipIfAsan
^^^^^^^^^^
NameError: name 'skipIfAsan' is not defined
```
This fixes issues found in e066f35c6981c720e3a7e5883efc40c861b3b7, which
was later reverted. The problem was with "k" message which was sent with
sync_on_timeout flag set to true, so lldb was waiting for response,
which is currently not being sent by lldb-server. Not waiting for
response at all seems to be not a solution, because on MAC OS X lldb
waits for response from "k" to gracefully kill inferior.
These fail with on the macOS ASAN CI with following error:
```
07:10:31 ======================================================================
07:10:31 FAIL: test_runInTerminalWithObjectEnv (TestDAP_runInTerminal.TestDAP_runInTerminal)
07:10:31 Tests the "runInTerminal" reverse request. It makes sure that the IDE can
07:10:31 ----------------------------------------------------------------------
07:10:31 Traceback (most recent call last):
07:10:31 File "/Users/ec2-user/jenkins/workspace/llvm.org/lldb-cmake-sanitized/llvm-project/lldb/packages/Python/lldbsuite/test/decorators.py", line 149, in wrapper
07:10:31 return func(*args, **kwargs)
07:10:31 File "/Users/ec2-user/jenkins/workspace/llvm.org/lldb-cmake-sanitized/llvm-project/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py", line 83, in test_runInTerminalWithObjectEnv
07:10:31 self.build_and_launch(program, runInTerminal=True, env={"FOO": "BAR"})
07:10:31 File "/Users/ec2-user/jenkins/workspace/llvm.org/lldb-cmake-sanitized/llvm-project/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py", line 488, in build_and_launch
07:10:31 return self.launch(program, **kwargs)
07:10:31 File "/Users/ec2-user/jenkins/workspace/llvm.org/lldb-cmake-sanitized/llvm-project/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py", line 470, in launch
07:10:31 self.assertTrue(
07:10:31 AssertionError: False is not true : launch failed (process exited during launch or attach)
07:10:31 Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/lldb-cmake-sanitized/lldb-build/bin/clang
```
These fail ever since they were enabled in https://github.com/llvm/llvm-project/pull/144954.
Skip these again when testing with ASAN.
In the same way that memory regions may be known from a core file but
not readable, tag segments can also have no content. For example:
```
$ readelf --segments core
<...>
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
<...>
LOAD 0x0000000000002000 0x0000ffff93899000 0x0000000000000000
0x0000000000000000 0x0000000000001000 RW 0x1000
<...>
LOPROC+0x2 0x0000000000008000 0x0000ffff93899000 0x0000000000000000
0x0000000000000000 0x0000000000001000 0x0
```
This happens if you have a restricted coredump filter or size limit.
The area of virtual memory this segment covers is 0x1000, or 4096 bytes
aka one tagged page. It's FileSiz would normally be 0x80. Tags are
packed 2 per byte and granules are 16 bytes. 4096 / 16 / 2 = 128 or
0x80.
But here it has no data, and in theory a corrupt file might have some
data but not all. This triggered an assert in
UnpackTagsFromCoreFileSegment and crashed lldb.
To fix this I have made UnpackTagsFromCoreFileSegment return an expected
and returned an error in this case instead of asserting. This will be
seen by the user, as shown in the added API test.
It is failing on our Windows on Arm bot:
AssertionError: False is not true : launch failed (Unimplemented)
Given that all the others are skipped on Windows, I assume this
failure is expected too.
This relands changes in #144424 for adding a count of DWO files
parsed/loaded and the total number of DWO files.
The previous PR was reverted in #145494 due to the newly added unit
tests failing on Windows and MacOS CIs since these platforms don't
support DWO. This change add an additional
`@add_test_categories(["dwo"])` to the new tests to
[skip](cd46354dbd/lldb/packages/Python/lldbsuite/test/test_categories.py (L56))
these tests on Windows/MacOS.
Original PR: #144424
### Testing
Ran unit tests
```
$ bin/lldb-dotest -p TestStats.py llvm-project/lldb/test/API/commands/statistics/basic/
----------------------------------------------------------------------
Ran 24 tests in 211.391s
OK (skipped=3)
```
lldb-server had limited support for single-stepping through the lr/sc
atomic sequence. This patch enhances that support for all possible
atomic sequences.
## Summary
A new `totalLoadedDwoFileCount` and `totalDwoFileCount` counters to
available statisctics when calling "statistics dump".
1. `GetDwoFileCounts ` is created, and returns a pair of ints
representing the number of loaded DWO files and the total number of DWO
files, respectively. An override is implemented for `SymbolFileDWARF`
that loops through each compile unit, and adds to a counter if it's a
DWO unit, and then uses `GetDwoSymbolFile(false)` to check whether the
DWO file was already loaded/parsed.
3. In `Statistics`, use `GetSeparateDebugInfo` to sum up the total
number of loaded/parsed DWO files along with the total number of DWO
files. This is done by checking whether the DWO file was already
successfully `loaded` in the collected DWO data, anding adding to the
`totalLoadedDwoFileCount`, and adding to `totalDwoFileCount` for all CU
units.
## Expected Behavior
- When binaries are compiled with split-dwarf and separate DWO files,
`totalLoadedDwoFileCount` would be the number of loaded DWO files and
`totalDwoFileCount` would be the total count of DWO files.
- When using a DWP file instead of separate DWO files,
`totalLoadedDwoFileCount` would be the number of parsed compile units,
while `totalDwoFileCount` would be the total number of CUs in the DWP
file. This should be similar to the counts we get from loading separate
DWO files rather than only counting whether a single DWP file was
loaded.
- When not using split-dwarf, we expect both `totalDwoFileCount` and
`totalLoadedDwoFileCount` to be 0 since no separate debug info is
loaded.
## Testing
**Manual Testing**
On an internal script that has many DWO files, `statistics dump` was
called before and after a `type lookup` command. The
`totalLoadedDwoFileCount` increased as expected after the `type lookup`.
```
(lldb) statistics dump
{
...
"totalLoadedDwoFileCount": 29,
}
(lldb) type lookup folly::Optional<unsigned int>::Storage
typedef std::conditional<true, folly::Optional<unsigned int>::StorageTriviallyDestructible, folly::Optional<unsigned int>::StorageNonTriviallyDestructible>::type
typedef std::conditional<true, folly::Optional<unsigned int>::StorageTriviallyDestructible, folly::Optional<unsigned int>::StorageNonTriviallyDestructible>::type
...
(lldb) statistics dump
{
...
"totalLoadedDwoFileCount": 2160,
}
```
**Unit test**
Added three unit tests that build with new "third.cpp" and "baz.cpp"
files. For tests with w/ flags `-gsplit-dwarf -gpubnames`, this
generates 2 DWO files. Then, the test incrementally adds breakpoints,
and does a type lookup, and the count should increase for each of these
as new DWO files get loaded to support these.
```
$ bin/lldb-dotest -p TestStats.py ~/llvm-sand/external/llvm-project/lldb/test/API/commands/statistics/basic/
----------------------------------------------------------------------
Ran 20 tests in 211.738s
OK (skipped=3)
```
Replace `isTestSupported` function with `skipIfBuildType` annotation.
Test that uses the `IsTestSupported` function are no longer run, as the
size of lldb-dap binary is now more than `1mb`.
Update the broken test.
Fixes#108621
We could probably check if the test now passes on `linux arm` since it
was disabled because it timed out. I experienced the timeout after
replacing the `IsTestSupported` with `skipIfBuildType`.
Patch fixes the sync-on-timeout logic in lldb and switches to qEcho
based ping, instead of qC. This fixes vRun message case, when there is
no process yet and qC returns an error.
This is breaking TestCreateAfterAttach.py on Ubuntu:
```
======================================================================
FAIL: test_create_after_attach_dwo (TestCreateAfterAttach.CreateAfterAttachTestCase.test_create_after_attach_dwo)
Test thread creation after process attach.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1804, in test_method
return attrvalue(self)
^^^^^^^^^^^^^^^
File "/home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/decorators.py", line 149, in wrapper
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/llvm-project/lldb/test/API/functionalities/thread/create_after_attach/TestCreateAfterAttach.py", line 36, in test_create_after_attach
self.runCmd("process attach -p " + str(pid))
File "/home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1005, in runCmd
self.assertTrue(self.res.Succeeded(), msg + output)
AssertionError: False is not true : Command 'process attach -p 1474309' did not return successfully
Error output:
error: attach failed: lost connection
```
on the buildbots for lldb-remote-linux-ubuntu, lldb-arm-ubuntu,
lldb-aarch64-ubuntu, lldb-arm-ubuntu.
In DebugCommunication, we currently are using 2 thread to drive
lldb-dap. At the moment, they make an attempt at only synchronizing the
`recv_packets` between the reader thread and the main test thread. Other
stateful properties of the debug session are not guarded by a
locks/mutex.
To mitigate this, I am moving any state updates to the main thread
inside the `_recv_packet` method to ensure that between calls to
`_recv_packet` the state does not change out from under us in a test.
This does mean the precise timing of events has changed slightly as a
result and I've updated the existing tests that fail for me locally with
this new behavior.
I think this should result in overall more predictable behavior, even if
the test is slow due to the host workload or architecture differences.
---------
Co-authored-by: Ebuka Ezike <yerimyah1@gmail.com>
In #134418 we added support to list/enable/disable `SystemRuntime` and
`InstrumentationRuntime` plugins. We limited it to those two plugin
types to flesh out the idea with a smaller change.
This PR adds support for the remaining plugin types. We now support all
the plugins that can be registered directly with the plugin manager.
Plugins that are added by loading shared objects are still not
supported.
When testing LLDB, we want to make sure to use the same Python as the
one we used to build it.
This patch uses the CMake variable `Python3_ROOT_DIR` to add the correct
Python to the `PATH` in LLDB lit tests, in order to ensure of this.
Please see https://github.com/swiftlang/swift/pull/82063 for the
original issue.
This is a continuation of https://github.com/swiftlang/swift/pull/82063.
As part of https://github.com/llvm/llvm-project/pull/143177, I moved the
non-libc++ specific formatting of `std::string`s out to `CxxStringTypes`
as MSVC's STL `std::string` can also be thought of a pointer+size pair.
I named this kind of string "string buffer".
This PR picks that change, so the MSVC PR can be smaller.
Unfortunately, libstdc++'s `std::string` does not fit this (it also uses
a different string printer function).
This resolves two FIXMEs in the libc++ tests, where empty u16 and u32
strings didn't have any prefix (u/U).