**Summary**
When filling out the LayoutInfo for a structure with the offsets
from DWARF, LLDB fills gaps in the layout by creating unnamed
bitfields and adding them to the AST. If we don't do this correctly
and our layout has overlapping fields, we will hat an assertion
in `clang::CGRecordLowering::lower()`. Specifically, if we have
a derived class with a VTable and a bitfield immediately following
the vtable pointer, we create a layout with overlapping fields.
This is an oversight in some of the previous cleanups done around this
area.
In `D76808`, we prevented LLDB from creating unnamed bitfields if there
was a gap between the last field of a base class and the start of a bitfield
in the derived class.
In `D112697`, we started accounting for the vtable pointer. The intention
there was to make sure the offset bookkeeping accounted for the
existence of a vtable pointer (but we didn't actually want to create
any AST nodes for it). Now that `last_field_info.bit_size` was being
set even for artifical fields, the previous fix `D76808` broke
specifically for cases where the bitfield was the first member of a
derived class with a vtable (this scenario wasn't tested so we didn't
notice it). I.e., we started creating redundant unnamed bitfields for
where the vtable pointer usually sits. This confused the lowering logic
in clang.
This patch adds a condition to `ShouldCreateUnnamedBitfield` which
checks whether the first field in the derived class is a vtable ptr.
**Testing**
* Added API test case
Differential Revision: https://reviews.llvm.org/D150591
This patch adds a new private helper
`DWARFASTParserClang::ShouldCreateUnnamedBitfield` which
`ParseSingleMember` whether we should fill the current gap
in a structure layout with unnamed bitfields.
Extracting this logic will allow us to add additional
conditions in upcoming patches without jeoperdizing readability
of `ParseSingleMember`.
We also store some of the boolean conditions in local variables
to make the intent more obvious.
Differential Revision: https://reviews.llvm.org/D150590
When `ValueObjectPrinter` calls its `m_decl_printing_helper`, not all state is passed to
the helper. In particular, the helper doesn't have access to `m_curr_depth`, and thus
can't act on the logic within `ShouldShowName`.
To address this, this change passes in a modified copy of `m_options`. The modified copy
has has `m_hide_name` set according to the results of `ShouldShowName`. This allows
helper functions to know whether the name should be shown or hidden, without having
access to `ValueObjectPrinter`'s full state.
This is NFC in mainline lldb, as the only decl printing helper doesn't make use of this.
However in swift-lldb at least, there are decl printing helpers that do need this
information passed to them. See https://github.com/apple/llvm-project/pull/6795 where a
test is also included.
Differential Revision: https://reviews.llvm.org/D150129
DissassemblerCreateInstance is a function pointer whos return type is
`Disassembler *`. But Disassembler::FindPlugin always returns a
DisassemblerSP, so there's no reason why we can't just create a
DisassemblerSP in the first place.
Differential Revision: https://reviews.llvm.org/D150235
This reverts commit 2bea2d7b07.
It introduced following failures on buildbot lldb-aarch64-windows:
lldb-api :: functionalities/process_save_core/TestProcessSaveCore.py
lldb-api :: python_api/symbol-context/TestSymbolContext.py
Differential Revision: https://reviews.llvm.org/D149625
DWARFAttribute is used in 2 classes: DWARFAbbreviationDecl and
DWARFAttributes. The former stores a std::vector of them and the latter
has a small structure called AttributeValue that contains a
DWARFAttribute. DWARFAttributes maintains a llvm::SmallVector of
AttributeValues.
My end goal is to have `DWARFAttributes` have a llvm::SmallVector
specialized on DWARFAttribute. In order to do that, we'll have to move
the other elements of AttributeValue into DWARFAttribute itself. But we
don't want to do this while DWARFAbbreviationDecl is using
DWARFAttribute because it will needlessly increase the size of
DWARFAbbreviationDecl. So instead I will create a small type containing
only what DWARFAbbreviationDecl needs and call it `AttributeSpec`. This
is the exact same thing that LLVM does today.
I've elected to swap std::vector for llvm::SmallVector here with a pre-allocated
size of 8. I've collected time and memory measurements before this change and
after it as well. Using a c++ project with 10,000 object files and no dSYM, I
place a breakpoint by file + lineno and see how long it takes to resolve.
Before this patch:
Time (mean ± σ): 13.577 s ± 0.024 s [User: 12.418 s, System: 1.247 s]
Total number of bytes allocated: 1.38 GiB
Total number of allocations: 6.47 million allocations
After this patch:
Time (mean ± σ): 13.287 s ± 0.020 s [User: 12.128 s, System: 1.250 s]
Total number of bytes allocated: 1.59 GiB
Total number of allocations: 4.61 million allocations
So we consume more memory than before, but we actually make less allocations on
average.
I also measured with an llvm::SmallVector with a pre-allocated size of 4 instead
of 8 to measure how well it performs:
Time (mean ± σ): 13.246 s ± 0.048 s [User: 12.074 s, System: 1.268 s]
Total memory consumption: 1.50 GiB
Total number of allocations: 5.74 million
Of course this data may look very different depending on the actual program
being debugged, but each of the object files had 100+ AbbreviationDeclarations
each with between 0 and 10 Attributes, so I feel this was a fair example to
consider.
Differential Revision: https://reviews.llvm.org/D150418
The purpose of this method is to get the list of attributes of a
DebugInfoEntry. Prior to this change we were passing in a mutable
reference to a DWARFAttributes object and having the method fill it in
for us while returning the size of the filled out list. But
instead of doing that, we can just return a `DWARFAttributes` object
ourselves since every caller creates a new list before calling
GetAttributes.
Differential Revision: https://reviews.llvm.org/D150402
Similar to dw_form_t, dw_attr_t is typedef'd to be a uint16_t. LLVM
defines their type `llvm::dwarf::Attribute` as an enum backed by a
uint16_t. Switching to the LLVM type buys us type checking and the
requirement of explicit casts.
Differential Revision: https://reviews.llvm.org/D150299
This patch fixes libstdc++ data formatter for reference/pointer to std::string.
The failure testcases are added which succeed with the patch.
Differential Revision: https://reviews.llvm.org/D150313
Most of the code changed here dates back to 2010, when LLDB was first
introduced upstream, as such it benefits from a slight cleanup.
The method "dump" is not used anywhere nor is it tested, so this commit removes
it.
The "findRanges" method returns a boolean which is never checked and indicates
whether the method found anything/assigned a range map to the out parameter.
This commit folds the out parameter into the return type of the method.
A handful of typedefs were also never used and therefore removed.
Differential Revision: https://reviews.llvm.org/D150363
wrong answer. Plus, it's useful in some places to have a way to force
the full stack to be created even in the face of
interruption. Moreover, most of the time when you're just getting
frames, you don't need to know the number of frames in the stack to
start with. You just keep calling
Thread::GetStackFrameAtIndex(index++) and when you get a null
StackFrameSP back, you're done. That's also more amenable to
interruption if you are doing some work frame by frame.
So this patch makes GetStackFrameCount always return the full count,
suspending interruption. I also went through all the places that use
GetStackFrameCount to make sure that they really needed the full stack
walk. In many cases, they did not. For instance frame select -r 10 was
getting the number of frames just to check whether cur_frame_idx + 10
was within the stack. It's better in that case to see if that frame
exists first, since that doesn't force a full stack walk, and only
deal with walking off the end of the stack if it doesn't...
I also added a test for some of these behaviors.
Differential Revision: https://reviews.llvm.org/D150236
lldb needs to find the virtual address of the mach header of a
binary. It first scans for a segment which starts at file offset
0, and uses the vmaddr of that segment. If no segment starts at
fileoff 0, it looks for a segment named __TEXT.
This patch changes the order of those, to first search for the TEXT
segment. We have a situation where binaries exist that have the
DATA segment first, which does not have the vmaddr of the mach header,
it merely happens to come first in the binary file. It's an unusual
arrangement, but not breaking any rules of Mach-O. So lldb needs
to handle this.
Differential Revision: https://reviews.llvm.org/D150239
rdar://109128418
selecting the "Most relevant" frame.
If you don't do that, then the correct frame gets selected, but it
happens AFTER the frame info gets printed in the stop message, so
you don't see the selected frame.
The test for this hid the issue because it ran `frame info` and
checked the result of that. That happens after the recognizer selects
the frame, and so it was right. But if the recognizer is working
correctly it will have already done the same printing in the stop
message, and this way we also verify that the stop message was right.
Differential Revision: https://reviews.llvm.org/D150315
Many SB classes have public constructors or methods involving types that
are private. Some are more obvious (e.g. containing lldb_private in the
name) than others (lldb::FooSP is usually std::shared_pointer<lldb_private::Foo>).
This commit explicitly does not address FileSP, so I'm leaving that one
alone for now.
Some of these were for other SB classes to use and should have been made
protected/private with a friend class entry added. Some of these were
public for some of the swig python helpers to use. I put all of those
functions into a class and made them static methods. The relevant SB
classes mark that class as a friend so they can access those
private/protected members.
I've also removed an outdated SBStructuredData test (can you guess which
constructor it was using?) and updated the other relevant tests.
Differential Revision: https://reviews.llvm.org/D150157
LLDB currently defines `dw_form_t` as a `uint16_t` which makes sense.
However, LLVM also defines a similar type `llvm::dwarf::Form` which is
an enum backed by a `uint16_t`. Switching to the llvm implementation
means that we can more easily interoperate with the LLVM DWARF code.
Additionally, we get some type checking out of this: I found that
DWARFAttribute had a method called `FormAtIndex` that returned a
`dw_attr_t`. Although `dw_attr_t` is also a `uint16_t` under the hood,
the type checking benefits here are undeniable: If this had returned a
something of different signedness/width, we could have had some bad
bugs.
Differential Revision: https://reviews.llvm.org/D150228
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 04aa943be8 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