The code inside Broadcaster makes usage of iterators using olden C++ coding
style. Hidden in this old style is a couple of N^2 loops: we iterate over a map
(sequentially), removing the first element that matches some predicate. The
search is _always_ done from the start of the map, which implies that, if the
map has N elements and if all matches happen on the second half of the map, then
we visit the first N/2 elements exactly N/2 * N/2 times.
Ideally some of the code here would benefit from `std::map`s own "erase_if", but
this is only available with C++20:
https://en.cppreference.com/w/cpp/container/map/erase_if
We spent quite some time trying to make these loops more elegant, but it is
surprisingly tricky to do so.
Differential Revision: https://reviews.llvm.org/D150219
The old way of lldb reading the on-disk shared cache is still in
the sources, but we use dyld SPI to inspect this binary now. This
code is no longer called.
The LEB128 type defined by the DWARF standard is explicitly a variable-length
encoding of an integer. LLDB had defined `uleb128` and `sleb128` types
to be 32-bit but in many places in both LLVM and LLDB we treat the maximum
width of LEB128 types to be 64, so let's remove these types and be
consistent.
Differential Revision: https://reviews.llvm.org/D150222
* As no format string is involved, avoid unecessary call into `Printf`
* Eliminate creation of a `std::string` to print a `StringRef`
Differential Revision: https://reviews.llvm.org/D150160
We had some custom classes that were used as the predicate for
`std::find_if`. It would be a lot simpler if we used lambdas instead.
Differential Revision: https://reviews.llvm.org/D150168
jGetLoadedDynamicLibrariesInfos has a mode where it will list
every binary in the process - the load address and filepath from dyld
SPI, and the mach-o header and load commands from a scan by debugserver
for perf reasons. With a large enough number of libraries, creating
that StructuredData representation of all of this, and formatting it
into an ascii string to send up to lldb, can grow debugserver's heap
size too large for some environments.
This patch adds a new report_load_commands:false boolean to the
jGetLoadedDynamicLibrariesInfos packet, where debugserver will now
only report the dyld SPI load address and filepath for all of the
binaries. lldb can then ask for the detailed information on
the process binaries in smaller chunks, and avoid debugserver
having ever growing heap use as the number of binaries inevitably
increases.
This patch also removes a version of jGetLoadedDynamicLibrariesInfos
for pre-iOS 10 and pre-macOS 10.12 systems where we did not use
dyld SPI. We can't back compile to those OS builds any longer
with modern Xcode.
Finally, it removes a requirement in DynamicLoaderMacOS that the
JSON reply from jGetLoadedDynamicLibrariesInfos include the
mod_date field for each binary. This has always been reported as
0 in modern dyld, and is another reason for packet growth in
the reply. debugserver still puts the mod_date field in its replies
for interop with existing lldb's, but we will be able to remove it
the field from debugserver's output after the next release cycle
when this patch has had time to circulate.
I'll add lldb support for requesting the load addresses only
and splitting the request up into chunks in a separate patch.
Differential Revision: https://reviews.llvm.org/D150158
rdar://107848326
Fix a mutation of `CommandAlias::m_option_args_sp`, which resulted in cases where
aliases would fail to run on second, and subsequent times.
For example, an alias such as:
```
command alias p1 p 1
```
When run the second time, the following error would be reported to the user:
```
error: expression failed to parse:
error: <user expression 1>:1:1: expression is not assignable
-- 1
^ ~
```
To fix this, `CommandAlias::Desugar` now constructs options to a freshly constructed
vector, rather than by appending to the results of `GetOptionArguments`.
rdar://107770836
Differential Revision: https://reviews.llvm.org/D150078
Windows uses COFF as an object file format and PE/COFF as an executable
file format. They are subtly different and certain elements of a COFF
file may not be present in an executable. Introduce a new plugin to add
support for the COFF object file format which is required to support
loading of modules built with -gmodules. This is motivated by Swift
which serialises debugging information into a PCM which is a COFF object
file.
Differential Revision: https://reviews.llvm.org/D149987
Reviewed By: bulbazord
Modular just announced a new language called Mojo. This patch adds an entry in the language list in LLDB for minimal support (e.g. being able to create a TypeSystem for this language). We will later add debug info entries when the language matures.
Re-lands 04aa943be8ed5c03092e2a90112ac638360ec253 with modifications
to fix tests.
I originally reverted this because it caused a test to fail on Linux.
The problem was that I inverted a condition on accident.
The `TypeSystemMap::m_mutex` guards against concurrent modifications
of members of `TypeSystemMap`. In particular, `m_map`.
`TypeSystemMap::ForEach` iterates through the entire `m_map` calling
a user-specified callback for each entry. This is all done while
`m_mutex` is locked. However, there's nothing that guarantees that
the callback itself won't call back into `TypeSystemMap` APIs on the
same thread. This lead to double-locking `m_mutex`, which is undefined
behaviour. We've seen this cause a deadlock in the swift plugin with
following backtrace:
```
int main() {
std::unique_ptr<int> up = std::make_unique<int>(5);
volatile int val = *up;
return val;
}
clang++ -std=c++2a -g -O1 main.cpp
./bin/lldb -o “br se -p return” -o run -o “v *up” -o “expr *up” -b
```
```
frame #4: std::lock_guard<std::mutex>::lock_guard
frame #5: lldb_private::TypeSystemMap::GetTypeSystemForLanguage <<<< Lock #2
frame #6: lldb_private::TypeSystemMap::GetTypeSystemForLanguage
frame #7: lldb_private::Target::GetScratchTypeSystemForLanguage
...
frame #26: lldb_private::SwiftASTContext::LoadLibraryUsingPaths
frame #27: lldb_private::SwiftASTContext::LoadModule
frame #30: swift::ModuleDecl::collectLinkLibraries
frame #31: lldb_private::SwiftASTContext::LoadModule
frame #34: lldb_private::SwiftASTContext::GetCompileUnitImportsImpl
frame #35: lldb_private::SwiftASTContext::PerformCompileUnitImports
frame #36: lldb_private::TypeSystemSwiftTypeRefForExpressions::GetSwiftASTContext
frame #37: lldb_private::TypeSystemSwiftTypeRefForExpressions::GetPersistentExpressionState
frame #38: lldb_private::Target::GetPersistentSymbol
frame #41: lldb_private::TypeSystemMap::ForEach <<<< Lock #1
frame #42: lldb_private::Target::GetPersistentSymbol
frame #43: lldb_private::IRExecutionUnit::FindInUserDefinedSymbols
frame #44: lldb_private::IRExecutionUnit::FindSymbol
frame #45: lldb_private::IRExecutionUnit::MemoryManager::GetSymbolAddressAndPresence
frame #46: lldb_private::IRExecutionUnit::MemoryManager::findSymbol
frame #47: non-virtual thunk to lldb_private::IRExecutionUnit::MemoryManager::findSymbol
frame #48: llvm::LinkingSymbolResolver::findSymbol
frame #49: llvm::LegacyJITSymbolResolver::lookup
frame #50: llvm::RuntimeDyldImpl::resolveExternalSymbols
frame #51: llvm::RuntimeDyldImpl::resolveRelocations
frame #52: llvm::MCJIT::finalizeLoadedModules
frame #53: llvm::MCJIT::finalizeObject
frame #54: lldb_private::IRExecutionUnit::ReportAllocations
frame #55: lldb_private::IRExecutionUnit::GetRunnableInfo
frame #56: lldb_private::ClangExpressionParser::PrepareForExecution
frame #57: lldb_private::ClangUserExpression::TryParse
frame #58: lldb_private::ClangUserExpression::Parse
```
Our solution is to simply iterate over a local copy of `m_map`.
**Testing**
* Confirmed on manual reproducer (would reproduce 100% of the time
before the patch)
Differential Revision: https://reviews.llvm.org/D149949
This patch resolves an issue where a value
is incorrectly displayed if it is represented
by DW_OP_div.
This issue is caused by lldb evaluating
operands of DW_OP_div as unsigned
and performed unintended unsigned
division.
This issue is resolved by creating two
temporary signed scalar and performing
signed division.
(Addresses GH#61727)
Differential Revision: https://reviews.llvm.org/D147370
Use templates to simplify {Get,Set}PropertyAtIndex. It has always
bothered me how cumbersome those calls are when adding new properties.
After this patch, SetPropertyAtIndex infers the type from its arguments
and GetPropertyAtIndex required a single template argument for the
return value. As an added benefit, this enables us to remove a bunch of
wrappers from UserSettingsController and OptionValueProperties.
Differential revision: https://reviews.llvm.org/D149774
There are many situations where we'll iterate over a SymbolContextList
with the pattern:
```
SymbolContextList sc_list;
// Fill in sc_list here
for (auto i = 0; i < sc_list.GetSize(); i++) {
SymbolContext sc;
sc_list.GetSymbolAtContext(i, sc);
// Do work with sc
}
```
Adding an iterator to iterate over the instances directly means we don't
have to do bounds checking or create a copy of every element of the
SymbolContextList.
Differential Revision: https://reviews.llvm.org/D149900
If a remote stub provides the addressing_bits kv pair in
the stop reply packet, update the Process address masks with
that value as it possibly changes during the process runtime.
This is an unusual situation, most likely a JTAG remote stub
and some very early startup code that is setting up the page
tables. Nearly all debug sessions will have a single address
mask that cannot change during the lifetime of a Process.
Differential Revision: https://reviews.llvm.org/D149803
rdar://61900565
REPL implementations don't have an easy way to know that an expression has been evaluated, so I'm adding a simple function for that. In the future we can add another hook for meta commands.
Differential Revision: https://reviews.llvm.org/D149719
The qHostInfo packet in the gdb-remote communication protocol specifies
that distribution_id can be set, so lldb handles that. But we store that
in the ArchSpec representing the "Host" platform (whatever platform the
debug server is running on). This field is otherwise unused in ArchSpec,
so it would be a lot easier if we stored that information at the
gdb-remote communication layer.
Sidenote: The distribution_id field is currently unused but I did not
want to remove it in case some folks found it useful (e.g. in downstream
forks).
Differential Revision: https://reviews.llvm.org/D149697
As far as I can tell, this just computes the filename of the FileSpec,
which is already conveniently stored in m_filename. We can use
FileSpec::GetFilename() instead.
Differential Revision: https://reviews.llvm.org/D149663
FileSpec::GetFileNameExtension returns a StringRef. In some cases we
are calling it and then storing the result in a local. To prevent
cases where we store the StringRef, mutate the Filespec, and then try to
use the stored StringRef afterwards, I've audited the callsites and made
adjustments to mitigate: Either marking the FileSpec it comes from as
const (to avoid mutations) or by not storing the StringRef in a local if
it makes sense not to.
Differential Revision: https://reviews.llvm.org/D149671
This is an optional request, but supporting it makes the experience
better when re-launching a big binary that takes significant time to
parse: instead of tearing down and re-create the whole session we just
need to kill the current process and launch a new one.
Some non-obvious comments that might help review this change:
* After killing the process, we get an "exited" event for it. Because
the process no longer exists some interesting things can occur that
manifest as flaky failures if not dealt with:
- `EventIsProcessEvent` relies on `SBEvent::GetBroadcasterClass`,
which can crash if the broadcaster is no longer there: the event
only holds a weak_ptr to its broadcaster, and `GetBroadcasterClass`
uses it without checking.
Other `EventIs*` functions look at the flavor of the EventData, so I
have modified EventIsProcessEvent to do that.
- We keep the PID of the old process so we can detect its "exited"
event and not terminate the whole session. But sometimes the
SBProcess we get from the event won't have a PID, for some reason.
* I have factored out the code to launch a process out to a new
LaunchProcess function, so it can be used from both `request_launch`
and `request_restart`.
* The restart_runInTerminal test has the same problem with debug builds
as the original runInTerminal test: when attaching to the launcher
instance of lldb-vscode it takes a long time to parse its debug info.
I have used the same workaround to disable that particular test for
debug builds.
Differential Revision: https://reviews.llvm.org/D147831
This reverts commit e15d6b520e1e85d2cdf9ffc66f0c4698390eaa3d.
Newly added test fails on Darwin platforms and arm.
Differential Revision: https://reviews.llvm.org/D147370
Expression evaluation allocates memory for storing intermediate data during evaluation. For it to work properly it has to be allocated within target's available address space, for example within first 0xFFFF bytes for the 16-bit MSP430. The memory for such targets can be very tightly packed, but not all targets support GetMemoryRegionInfo API to pick an unused region, like MSP430 with MSPDebug GDB server.
These settings allow the programmer to manually pick precisely where and how much memory to allocate for expression evaluation in order not to overlap with existing data in process memory.
Reviewed By: bulbazord
Differential Revision: https://reviews.llvm.org/D149262
The majority of call sites are nullptr as the execution context.
Refactor OptionValueProperties to make the argument optional and
simplify all the callers.
There's no reason to create an entire new filespec to mutate and grab
data from when we can just grab the data directly.
Differential Revision: https://reviews.llvm.org/D149625
This patch resolves an issue where a value
is incorrectly displayed if it is represented
by DW_OP_div.
This issue is caused by lldb evaluating
operands of DW_OP_div as unsigned
and performed unintended unsigned
division.
This issue is resolved by creating two
temporary signed scalar and performing
signed division.
(Addresses GH#61727)
Differential Revision: https://reviews.llvm.org/D147370
Various OptionValue related classes are passing around will_modify but
the value is never used. This patch simplifies the interfaces by
removing the redundant argument.
Similar to fdbe7c7faa54, refactor OptionValueProperties to return a
std::optional instead of taking a fail value. This allows the caller to
handle situations where there's no value, instead of being unable to
distinguish between the absence of a value and the value happening the
match the fail value. When a fail value is required,
std::optional::value_or() provides the same functionality.
Refactor OptionValue to return a std::optional instead of taking a fail
value. This allows the caller to handle situations where there's no
value, instead of being unable to distinguish between the absence of a
value and the value happening the match the fail value. When a fail
value is required, std::optional::value_or() provides the same
functionality.
llvm has a structure for maps where the key's type is a string. Using
that also means that the keys for OptionValueDictionary don't stick
around forever in ConstString's StringPool (even after they are gone).
The only thing we lose here is ordering: iterating over the map where the keys
are ConstStrings guarantees that we iterate in alphabetical order.
StringMap makes no guarantees about the ordering when you iterate over
the entire map.
Differential Revision: https://reviews.llvm.org/D149482