The only change vs. the first version of the patch is that I've made
DWARFUnit linking thread-safe/unit. This was necessary because, during
the
indexing step, two skeleton units could attempt to associate themselves
with the split unit.
The original commit message was:
I ran into this when LTO completely emptied two compile units, so they
ended up with the same hash (see #100375). Although, ideally, the
compiler would try to ensure we don't end up with a hash collision even
in this case, guaranteeing their absence is practically impossible. This
patch ensures this situation does not bring down lldb.
This patch improves the ability of a ObjectFileELF instance to read the
.dynamic section. It adds the ability to read the .dynamic section from
the PT_DYNAMIC program header which is useful for ELF files that have no
section headers and for ELF files that are read from memory. It cleans
up the usage of the .dynamic entries so that
ObjectFileELF::ParseDynamicSymbols() is the only code that parses
.dynamic entries, teaches that function the read and store the string
values for each .dynamic entry. We now dump the .dynamic entries in the
output of "image dump objfile". It also cleans up the code that gets the
dynamic string table so that it can grab it from the DT_STRTAB and
DT_STRSZ .dynamic entries for when we have a ELF file with no section
headers or we are reading it from memory.
The test appears to be flaky. Revert it while I investigate.
This reverts commits 32a62ebdeab0c10d5311cf812e021717636d4514 and
7027cc6a073cb5ae7a0ce04fa4a2dbe714615da9.
The test appears to be flaky. Revert it while I investigate.
This reverts commits 7027cc6a073cb5ae7a0ce04fa4a2dbe714615da9 and
21ef272ec1974244710fc639f98674eae3f8b02c.
…Type
This is needed to ensure we find a type if its definition is in a CU
that wasn't indexed. This can happen if the definition is in some
precompiled code (e.g. the c++ standard library) which was built with
different flags than the rest of the binary.
I ran into this when LTO completely emptied two compile units, so they
ended up with the same hash (see #100375). Although, ideally, the
compiler would try to ensure we don't end up with a hash collision even
in this case, guaranteeing their absence is practically impossible. This
patch ensures this situation does not bring down lldb.
This patch improves the ability of a ObjectFileELF instance to read the .dynamic section. It adds the ability to read the .dynamic section from the PT_DYNAMIC program header which is useful for ELF files that have no section headers and for ELF files that are read from memory. It cleans up the usage of the .dynamic entries so that ObjectFileELF::ParseDynamicSymbols() is the only code that parses .dynamic entries, teaches that function the read and store the string values for each .dynamic entry. We now dump the .dynamic entries in the output of "image dump objfile". It also cleans up the code that gets the dynamic string table so that it can grab it from the DT_STRTAB and DT_STRSZ .dynamic entries for when we have a ELF file with no section headers or we are reading it from memory.
This fixes a regression caused by delayed type definition searching
(#96755 and friends): If we end up adding a member (e.g. a typedef) to a
type that we've already attempted to complete (and failed), the
resulting AST would end up inconsistent (we would start to "forcibly"
complete it, but never finish it), and importing it into an expression
AST would crash.
This patch fixes this by detecting the situation and finishing the
definition as well.
This patch renames the `scripting template` subcommand to be `scripting
extension` instead since that would make more sense for upcoming
commands.
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
This is an alternative, much simpler implementation of #99305. In this
version I replace the AnyModule wildcard match with a special TypeQuery
flag which achieves (mostly) the same thing.
It is a preparatory step for teaching ContextMatches about anonymous
namespaces. It started out as a way to remove the assumption that the
pattern and target contexts must be of the same length -- that's will
not be correct with anonymous namespaces, and probably isn't even
correct right now for AnyModule matches.
For the same reasons as 6cfac497e96978f2bfc50a00b51c198f2ed50f82.
This test was added in https://github.com/llvm/llvm-project/pull/100710.
It fails because when we're linking with link.exe, -gdwarf has no
effect and we get a PDB file anyway. The Windows on Arm lldb bot
uses link.exe.
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.34.31933\\bin\\Hostx86\\arm64\\link.exe" <...>
08/01/2024 01:47 PM 2,956,488 vla.cpp.ilk
08/01/2024 01:47 PM 6,582,272 vla.cpp.pdb
08/01/2024 01:47 PM 734,208 vla.cpp.tmp
Depends on https://github.com/llvm/llvm-project/pull/100674
Currently, we treat VLAs declared as `int[]` and `int[0]` identically.
I.e., we create them as `IncompleteArrayType`s. However, the
`DW_AT_count` for `int[0]` *does* exist, and is retrievable without an
execution context. This patch decouples the notion of "has 0 elements"
from "has no known `DW_AT_count`".
This aligns with how Clang represents `int[0]` in the AST (it treats it
as a `ConstantArrayType` of 0 size).
This issue was surfaced when adapting LLDB to
https://github.com/llvm/llvm-project/issues/93069. There, the
`__compressed_pair_padding` type has a `char[0]` member. If we
previously got the `__compressed_pair_padding` out of a module (where
clang represents `char[0]` as a `ConstantArrayType`), and try to merge
the AST with one we got from DWARF (where LLDB used to represent
`char[0]` as an `IncompleteArrayType`), the AST structural equivalence
check fails, resulting in silent ASTImporter failures. This manifested
in a failure in `TestNonModuleTypeSeparation.py`.
**Implementation**
1. Adjust `ParseChildArrayInfo` to store the element counts of each VLA
dimension as an `optional<uint64_t>`, instead of a regular `uint64_t`.
So when we pass this down to `CreateArrayType`, we have a better
heuristic for what is an `IncompleteArrayType`.
2. In `TypeSystemClang::GetBitSize`, if we encounter a
`ConstantArrayType` simply return the size that it was created with. If
we couldn't determine the authoritative bound from DWARF during parsing,
we would've created an `IncompleteArrayType`. This ensures that
`GetBitSize` on arrays with `DW_AT_count 0x0` returns `0` (whereas
previously it would've returned a `std::nullopt`, causing that
`FieldDecl` to just get dropped during printing)
The help output incorrectly states that this command takes a shared
library name (<shlib-name>) while really it takes a path to a symbol
file.
rdar://131777043
This patch adds a frame recognizer for Clang's
`__builtin_verbose_trap`, which behaves like a
`__builtin_trap`, but emits a failure-reason string into debug-info in
order for debuggers to display
it to a user.
The frame recognizer triggers when we encounter
a frame with a function name that begins with
`__clang_trap_msg`, which is the magic prefix
Clang emits into debug-info for verbose traps.
Once such frame is encountered we display the
frame function name as the `Stop Reason` and display that frame to the
user.
Example output:
```
(lldb) run
warning: a.out was compiled with optimization - stepping may behave oddly; variables may not be available.
Process 35942 launched: 'a.out' (arm64)
Process 35942 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = Misc.: Function is not implemented
frame #1: 0x0000000100003fa4 a.out`main [inlined] Dummy::func(this=<unavailable>) at verbose_trap.cpp:3:5 [opt]
1 struct Dummy {
2 void func() {
-> 3 __builtin_verbose_trap("Misc.", "Function is not implemented");
4 }
5 };
6
7 int main() {
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = Misc.: Function is not implemented
frame #0: 0x0000000100003fa4 a.out`main [inlined] __clang_trap_msg$Misc.$Function is not implemented$ at verbose_trap.cpp:0 [opt]
* frame #1: 0x0000000100003fa4 a.out`main [inlined] Dummy::func(this=<unavailable>) at verbose_trap.cpp:3:5 [opt]
frame #2: 0x0000000100003fa4 a.out`main at verbose_trap.cpp:8:13 [opt]
frame #3: 0x0000000189d518b4 dyld`start + 1988
```
PT_LOAD and PT_TLS segments are top level sections in the ObjectFileELF
section list. The two segments can often have the same program header
p_vaddr and p_paddr values and this can cause section load list issues
in LLDB if we load the PT_TLS segments. What happens is the
SectionLoadList::m_addr_to_sect, when a library is loaded, will first
map one of the sections named "PT_LOAD[0]" with the load address that
matches the p_vaddr entry from the program header. Then the "PT_TLS[0]"
would come along and try to load this section at the same address. This
would cause the "PT_LOAD[0]" section to be unloaded as the
SectionLoadList::m_addr_to_sect would replace the value for the matching
p_vaddr with the last section to be seen. The sizes of the PT_TLS and
PT_LOAD that have the same p_vaddr value don't need to have the same
byte size, so this could cause lookups to fail for an addresses in the
"PT_LOAD[0]" section or any of its children if the offset is greater
than the offset size of the PT_TLS segment. It could also cause us to
incorrectly attribute addresses from the "PT_LOAD[0]" to the "PT_TLS[0]"
segment when doing lookups for offset that are less than the size of the
PT_TLS segment.
This fix stops us from loading PT_TLS segments in the section load lists
and will prevent the bugs that resulted from this. No addresses the the
DWARF refer to TLS data with a "file address" in any way. They all have
TLS DWARF location expressions to locate these variables. We also don't
have any support for having actual thread specific sections and having
those sections resolve to something different for each thread, so there
currently is no point in loading thread specific sections. Both the
ObjectFileMachO and ObjectFileCOFF both ignore thread specific sections
at the moment, so this brings the ObjectFileELF to parity with those
plug-ins.
I added a test into an existing test to verify that things work as
expected.
Prior to this fix with a real binary, the output of "target dump
section-load-list" would look like this for the old LLDB:
```
// (lldb) target dump section-load-list
// addr = 0x0000000000000000, section = 0x55d46ab8c510: 0xfffffffffffffffd container [0x0000000000000000-0x0000000000000628) r-- 0x00000000 0x00000628 0x00000000 a.out.PT_LOAD[0]
// addr = 0x0000000000001000, section = 0x55d46ab8b0c0: 0xfffffffffffffffc container [0x0000000000001000-0x0000000000001185) r-x 0x00001000 0x00000185 0x00000000 a.out.PT_LOAD[1]
// addr = 0x0000000000002000, section = 0x55d46ac040f0: 0xfffffffffffffffb container [0x0000000000002000-0x00000000000020cc) r-- 0x00002000 0x000000cc 0x00000000 a.out.PT_LOAD[2]
// addr = 0x0000000000003db0, section = 0x55d46ab7cef0: 0xfffffffffffffff6 container [0x0000000000003db0-0x0000000000003db4) r-- 0x00002db0 0x00000000 0x00000000 a.out.PT_TLS[0]
```
And this for the fixed LLDB:
```
// (lldb) target dump section-load-list
// addr = 0x0000000000000000, section = 0x105f0a9a8: 0xfffffffffffffffd container [0x0000000000000000-0x0000000000000628) r-- 0x00000000 0x00000628 0x00000000 a.out.PT_LOAD[0]
// addr = 0x0000000000001000, section = 0x105f0adb8: 0xfffffffffffffffc container [0x0000000000001000-0x0000000000001185) r-x 0x00001000 0x00000185 0x00000000 a.out.PT_LOAD[1]
// addr = 0x0000000000002000, section = 0x105f0af48: 0xfffffffffffffffb container [0x0000000000002000-0x00000000000020cc) r-- 0x00002000 0x000000cc 0x00000000 a.out.PT_LOAD[2]
// addr = 0x0000000000003db0, section = 0x105f0b078: 0xfffffffffffffffa container [0x0000000000003db0-0x0000000000004028) rw- 0x00002db0 0x00000274 0x00000000 a.out.PT_LOAD[3]
```
We can see that previously the "PT_LOAD[3]" segment would be removed
from the section load list, and after the fix it remains and there is on
PT_TLS in the loaded sections.
Use `--match-full-lines` with FileCheck. Otherwise, the checks for `int`
and `unsigned int` will match to the fields inside two `CustomType`s and
FileCheck will start scanning from there, causing string not found
error.
Currently, LLDB prints out a rather unhelpful error message when passed
a file that it doesn't recognize as an executable.
> error: '/path/to/file' doesn't contain any 'host' platform
> architectures: arm64, armv7, armv7f, armv7k, armv7s, armv7m, armv7em,
> armv6m, armv6, armv5, armv4, arm, thumbv7, thumbv7k, thumbv7s,
> thumbv7f, thumbv7m, thumbv7em, thumbv6m, thumbv6, thumbv5, thumbv4t,
> thumb, x86_64, x86_64, arm64, arm64e
I did a quick search internally and found at least 24 instances of users
being confused by this. This patch improves the error message when it
doesn't recognize the file as an executable, but keeps the existing
error message otherwise, i.e. when it's an object file we understand,
but the current platform doesn't support.
This reverts commit 927def49728371d746476e79a6570cd93a4d335c.
I've refactored the tests so that we're explicit about whether the
enum is signed or not. Which means we use the proper types
throughout.
Fixes#97514
Given this example:
```
enum E {};
int main()
{
E x = E(0);
E y = E(1);
E z = E(2);
return 0;
}
```
lldb used to print nothing for `x`, but `0x1` for `y` and `0x2` for `z`.
At first this seemed like the 0 case needed fixing but the real issue
here is that en enum with no enumerators was being detected as a
"bitfield like enum".
Which is an enum where all enumerators are a single bit value, or the
sum of previous single bit values.
For these we do not print anything for a value of 0, as we assume it
must be the remainder after we've printed the other bits that were set
(I think this is also unfortunate, but I'm not addressing that here).
Clearly an enum with no enumerators cannot be being used as a bitfield,
so check that up front and print it as if it's a normal enum where we
didn't match any of the enumerators. This means you now get:
```
(lldb) p x
(E) 0
(lldb) p y
(E) 1
(lldb) p z
(E) 2
```
Which is a change to decimal from hex, but I think it's overall more
consistent. Printing hex here was never a concious decision.
This enables XML output for enums and adds enums for 2 fields on AArch64
Linux:
* mte_ctrl.tcf, which controls how tag faults are delivered.
* fpcr.rmode, which sets the rounding mode for floating point
operations.
The other one we could do is cpsr.btype, but it is not clear what would
be useful here so I'm not including it in this change.
This extends the existing register fields support from AArch64 Linux
to AArch64 FreeBSD. So you will now see output like this:
```
(lldb) register read cpsr
cpsr = 0x60000200
= (N = 0, Z = 1, C = 1, V = 0, DIT = 0, SS = 0, IL = 0, SSBS = 0, D = 1, A = 0, I = 0, F = 0, nRW = 0, EL = 0, SP = 0)
```
Linux and FreeBSD both have HWCAP/HWCAP2 so the detection mechanism
is the same and I've renamed the detector class to reflect that.
I have confirmed that FreeBSD's treatment of CPSR (spsr as the kernel
calls it) is similair enough that we can use the same field information.
(see `sys/arm64/include/armreg.h` and `PSR_SETTABLE_64`)
For testing I've enabled the same live process test as Linux
and added a shell test using an existing FreeBSD core file.
Note that the latter does not need XML support because when reading
a core file we are not sending the information via target.xml,
it's just internal to LLDB.
Follow-up to https://github.com/llvm/llvm-project/pull/96932
Adds XFAILed test where LLDB incorrectly infers the alignment of a
derived class whose bases are overlapping due to [[no_unique_address]].
Specifically, the `InferAlignment` code-path of the
`ItaniumRecordLayoutBuilder` assumes that overlapping base offsets imply
a packed structure and thus sets alignment to 1. See discussion in
https://github.com/llvm/llvm-project/pull/93809.
Also adds test where LLDB correctly infers an alignment of `1` when a
packed base class is overlapping with other bases.
Lastly, there were a couple of `alignof` inconsistencies which I
encapsulated in an XFAIL-ed `packed-alignof.cpp`.
When we check for the "struct CustomType" in the NODWP, we can just make
sure that we have both types showing up, the next tests will validate
the types are correct. Also added a "-DAG" to the integer and float
types. This should fix the flakiness in this test.
Adds test that checks whether LLDB correctly infers the
alignment of packed structures. Specifically, the
`InferAlignment` code-path of the `ItaniumRecordLayoutBuilder`
where it assumes that overlapping field offsets imply a
packed structure and thus sets alignment to `1`. See discussion
in https://github.com/llvm/llvm-project/pull/93809.
While here, also added a test-case where we check alignment of
a class whose base has an explicit `DW_AT_alignment
(those don't get transitively propagated in DWARF, but don't seem
like a problem for LLDB).
Lastly, also added an XFAIL-ed tests where the aforementioned
`InferAlignment` kicks in for overlapping fields (but in this
case incorrectly since the structure isn't actually packed).
This is a regression from #96484 caught by @ZequanWu.
Note that we will still create separate enum types for types parsed from
two definitions. This is different from how we handle classes, but it is
not a regression.
I'm also adding the DieToType check to the class type parsing code,
although in this case, the type uniqueness should be enforced by the
UniqueDWARFASTType map.
from PEP8
(https://peps.python.org/pep-0008/#programming-recommendations):
> Comparisons to singletons like None should always be done with is or
is not, never the equality operators.
Co-authored-by: Eisuke Kawashima <e-kwsm@users.noreply.github.com>
This patch adds support for the new foreign type unit support in
.debug_names. Features include:
- don't manually index foreign TUs if we have info for them
- only use the type unit entries that match the .dwo files when we have
a .dwp file
- fix type unit lookups for .dwo files
- fix crashers that happen due to PeekDIEName() using wrong offsets where an entry had DW_IDX_comp_unit and DW_IDX_type_unit entries and when we had no type unit support, it would cause us to think it was a normal DIE in .debug_info from the main executable.
---------
Co-authored-by: paperchalice <liujunchang97@outlook.com>
Our dwarf parsing code treats structures and classes as interchangable.
CompilerContextKind is used when looking DIEs for types. This makes sure
we always they're treated the same way.
See also
[#95905#discussion_r1645686628](https://github.com/llvm/llvm-project/pull/95905#discussion_r1645686628).
This relands https://github.com/llvm/llvm-project/pull/95963. It had to
be reverted because the `TestEarlyProcessLaunch.py` test was failing
on the incremental macOS bots. The test failed because it was relying on
expression log output from the ObjC introspection routines (but was
the expression was called from a C++ context). The relanded patch
simply ensures that the test runs the expressions as `ObjC` expressions.
When LLDB isn't able to find a `clang::Decl` in response
to a `FindExternalVisibleDeclsByName`, it will fall-back
to looking into the Objective-C runtime for that decl. This
ends up doing a lot of work which isn't necessary when we're
debugging a C++ program. This patch makes the ObjC lookup
conditional on the language that the ExpressionParser deduced
(which can be explicitly set using the `expr --language` option
or is set implicitly if we're stopped in an ObjC frame or a
C++ frame without debug-info).
rdar://96236519
This patch makes interactive mode as the default when using the crashlog
command. It replaces the existing `-i|--interactive` flag with a new
`-m|--mode` option, that can either be `interactive` or `batch`.
By default, when the option is not explicitely set by the user, the
interactive mode is selected, however, lldb will fallback to batch mode
if the command interpreter is not interactive or if stdout is not a tty.
This also adds some railguards to prevent users from using interactive
only options with the batch mode and updates the tests accordingly.
rdar://97801509
Differential Revision: https://reviews.llvm.org/D141658
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
This change by itself has no measurable effect on the LLDB
testsuite. I'm making it in preparation for threading through more
errors in the Swift language plugin.
With simple template names the template arguments aren't embedded in the
DW_AT_name attribute of the type. The code in
FindDefinitionTypeForDWARFDeclContext was comparing the synthesized
template arguments on the leaf (most deeply nested) DIE, but was not
sufficient, as the difference get be at any level above that
(Foo<T>::Bar vs. Foo<U>::Bar). This patch makes sure we compare the
entire context.
As a drive-by I also remove the completely unnecessary
ConstStringification of the GetDIEClassTemplateParams result.
The following warning is technically correct, but pretty much useless,
since there aren't any frame variables that we'd expect the debugger to
understand.
> This version of LLDB has no plugin for the language "assembler".
> Inspection of frame variables will be limited.
This message is useful in the general case but should be suppressed for
the "assembler" case.
rdar://92745462
This is a minimal reproducer for a crash where we would try to call
`DumpTypeDescription` on an incomplete type. This crash surfaced as part
of an NFC refactor of some of the logic in `GetCompleteQualType`:
```
(lldb) expr -l objc -- *(id)0x1234
Stack dump:
0. Program arguments: ./bin/lldb a.out -o "b main" -o run -o "expr -l objc -- *(id)0x1234"
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var LLVM_SYMBOLIZER_PATH to point to it):
0 lldb 0x0000000102ec768c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1 lldb 0x0000000102ec6010 llvm::sys::RunSignalHandlers() + 112
2 lldb 0x0000000102ec7fa8 SignalHandler(int) + 292
3 libsystem_platform.dylib 0x000000018c7a8c44 _sigtramp + 56
4 LLDB 0x0000000116b2030c lldb_private::TypeSystemClang::DumpTypeDescription(void*, lldb_private::Stream&, lldb::DescriptionLevel, lldb_private::ExecutionContextScope*) + 588
5 LLDB 0x00000001166b5124 lldb_private::CompilerType::DumpTypeDescription(lldb_private::Stream*, lldb::DescriptionLevel, lldb_private::ExecutionContextScope*) const + 228
6 LLDB 0x0000000116d4f08c IRForTarget::CreateResultVariable(llvm::Function&) + 2076
```
rdar://129633122
Use the packaging [1] module for parsing version numbers, instead of
pkg_resources which is distributed with setuptools. I recently switched
over to using the latter, knowing it was deprecated (in favor of the
packaging module) because it comes with Python out of the box. Newer
versions of setuptools have removed `pkg_resources` so we have to use
packaging.
[1] https://pypi.org/project/packaging/