Currently we forcefully complete C++ types if we can't find their
definition for layout purposes. This ensures that we at least don't
crash in Clang when laying out the type. The definition is required for
types of members/array elements/base classes for the purposes of
calculating their layout. This is also true for Obj-C types, but we
haven't been forcefully completing those.
The test-case that's being un-XFAILed in this patch demonstrates a case
where not completing the super-class forcefully causes a clang crash.
rdar://168440264
LLDB currently crashes when the super-class of an Objective-C type can't
be completed (i.e., has no definition). For Foundation types such as
`NSObject`, the debug-info would usually only contain forward
declarations. The definitions live in the Clang module `.pcm` files. But
if the source of the definition fails to be loaded (e.g., if we just
delete the module cache), then we can no longer guarantee that the
super-class has a definition. This breaks a key Clang invariant, which
requires base-classes to have definitions by the time we try to lay them
out. This patch adds an XFAILed test for such scenario.
rdar://168440264
Trimming the content of the progress event is the responsibility of the
consumer, not the producer. For example, when using the statusline,
there's plenty of space to show longer expressions.
rdar://166879951
We fall back to `Objective-C++` when running C++ expressions in frames
that don't have debug-info. But we were missing a fallback note for this
situation. We would now print following note on expression error:
```
note: Possibly stopped inside system library, so speculatively enabled Objective-C. Ran expression as 'Objective C++'.
```
Depends on:
* https://github.com/llvm/llvm-project/pull/166917
* https://github.com/llvm/llvm-project/pull/166940
While these errors can contribute to an expression failing, they are
never *the* reason the expression failed. I.e., they are always just
'note:' diagnostics that we hand-emit. Because they are quite noisy (and
we potentially have many of them if we auto-load all modules in a CU),
this patch logs the errors to the `expr` log, instead of the console.
Previously these errors would only get omitted when the expression
itself failed. Meaning if the expression failed, we'd dump these 'note'
module load errors in next to the actual expression error, obscuring the
output. Moreover, if the expression succeeded, any module load errors
would be dropped. Now we always log all module loading errors to the
expression log, regardless of whether the expression fails or not.
Depends on:
* https://github.com/llvm/llvm-project/pull/166917
When loading all Clang modules for a CU, we stop on first error. This
means benign module loading errors may stop us from importing actually
useful modules. There's no good reason to bail on the first one. The
pathological case would be if we try to load a large number of Clang
modules
but all fail to load for the same reason. That could happen, but in
practice I've always seen only a handful of modules failing to load out
of a large number. Particularly system modules are useful and usually
don't fail to load. Whereas project-specific Clang modules are more
likely to fail because the build system moves the modulemap/sources
around.
This patch accumulates all module loading errors and doesn't stop when
an error is encountered.
Instead of propagating the errors as a `bool`+`Stream` we change the
`ClangModulesDeclVendor` module loading APIs to use `llvm::Error`. We
also reword some of the diagnostics (notably removing the hardcoded
`error:` prefix). A follow-up patch will further make the module loading
errors less noisy.
See the new tests for what the errors look like.
rdar://164002569
Most of the cases were where a C++ file was being compiled with the C substitution.
There were a few cases of the opposite though.
LLDB seems to be the only real culprit in the LLVM codebase for these mismatches.
Rest of the LLVM presumably sticks at least language-specific options in the common substitutions
making the mistakes immediately apparent.
I found these by using Clang frontend configuration files containing language-specific options for
both C and C++ (e.g. `-std=c2y` and `-std=c++26`).
This still fails on Windows because the default language for the C++
frame is not the same as on Unix.
Also remove the LLD requirement, since we're not relying on DWARF here.
Otherwise debug-info is stripped, which influences the language of the
current frame.
Also, set explicit breakpoint because Windows seems to not obey the
debugtrap.
Log from failing test on Windows:
```
(lldb) command source -s 0 'lit-lldb-init-quiet'
Executing commands in 'D:\test\lit-lldb-init-quiet'.
(lldb) command source -C --silent-run true lit-lldb-init
(lldb) target create "main.out"
Current executable set to 'D:\test\main.out' (x86_64).
(lldb) settings set interpreter.stop-command-source-on-error false
(lldb) command source -s 0 'with-target.input'
Executing commands in 'D:\test\with-target.input'.
(lldb) expr blah
^
error: use of undeclared identifier 'blah'
note: Falling back to default language. Ran expression as 'Objective C++'.
(lldb) run
Process 29404 launched: 'D:\test\main.out' (x86_64)
Process 29404 stopped
* thread #1, stop reason = Exception 0x80000003 encountered at address 0x7ff7b3df7189
frame #0: 0x00007ff7b3df718a main.out
-> 0x7ff7b3df718a: xorl %eax, %eax
0x7ff7b3df718c: popq %rcx
0x7ff7b3df718d: retq
0x7ff7b3df718e: int3
(lldb) expr blah
^
error: use of undeclared identifier 'blah'
note: Falling back to default language. Ran expression as 'Objective C++'.
(lldb) expr -l objc -- blah
^
error: use of undeclared identifier 'blah'
note: Expression evaluation in pure Objective-C not supported. Ran expression as 'Objective C++'.
(lldb) expr -l c -- blah
^
error: use of undeclared identifier 'blah'
note: Expression evaluation in pure C not supported. Ran expression as 'ISO C++'.
```
Depends on:
* https://github.com/llvm/llvm-project/pull/162050
Since it's a 'Note' diagnostic it would only show up when expression
evaluation actually failed. This helps with expression evaluation
failure reports in mixed language environments where it's not quite
clear what language the expression ran as. It may also reduce confusion
around why the expression evaluator ran an expression in a language it
wasn't asked to run (a softer alternative to what I attempted in
https://github.com/llvm/llvm-project/pull/156648).
Here are some example outputs:
```
# Without target
(lldb) expr blah
note: Falling back to default language. Ran expression as 'Objective C++'.
# Stopped in target
(lldb) expr blah
note: Ran expression as 'C++14'.
(lldb) expr -l objc -- blah
note: Expression evaluation in pure Objective-C not supported. Ran expression as 'Objective C++'.
(lldb) expr -l c -- blah
note: Expression evaluation in pure C not supported. Ran expression as 'ISO C++'.
(lldb) expr -l c++14 -- blah
note: Ran expression as 'C++14'
(lldb) expr -l c++20 -- blah
note: Ran expression as 'C++20'
(lldb) expr -l objective-c++ -- blah
note: Ran expression as 'Objective C++'
(lldb) expr -l D -- blah
note: Expression evaluation in D not supported. Falling back to default language. Ran expression as 'Objective C++'.
```
I didn't put the diagnostic on the same line as the inline diagnostic
for now because of implementation convenience, but if reviewers deem
that a blocker I can take a stab at that again.
Also, other language plugins (namely Swift), won't immediately benefit
from this and will have to emit their own diagnistc. I played around
with having a virtual API on `UserExpression` or `ExpressionParser` that
will be called consistently, but by the time we're about to parse the
expression we are already several frames deep into the plugin. Before
(and at the beginning of) the generic `UserExpression::Parse` call we
don't have enough information to notify which language we're going to
parse in (at least for the C++ plugin).
rdar://160297649
rdar://159669244
Failing with:
```
error: command failed with exit status: 1
executed command: 'c:\buildbot\as-builder-10\lldb-x86-64\build\bin\filecheck.exe' 'C:\buildbot\as-builder-10\lldb-x86-64\llvm-project\lldb\test\Shell\Expr\TestGlobalSymbolObjCConflict.c'
.---command stderr------------
| C:\buildbot\as-builder-10\lldb-x86-64\llvm-project\lldb\test\Shell\Expr\TestGlobalSymbolObjCConflict.c:30:11: error: CHECK: expected string not found in input
| // CHECK: (lldb) p OglobalVar
| ^
| <stdin>:1:1: note: scanning from here
| (lldb) command source -s 0 'C:/buildbot/as-builder-10/lldb-x86-64/build/tools/lldb\test\Shell\lit-lldb-init-quiet'
| ^
| <stdin>:4:1: note: possible intended match here
| (lldb) target create "C:\\buildbot\\as-builder-10\\lldb-x86-64\\build\\tools\\lldb\\test\\Shell\\Expr\\Output\\TestGlobalSymbolObjCConflict.c.tmp.out"
| ^
|
| Input file: <stdin>
| Check file: C:\buildbot\as-builder-10\lldb-x86-64\llvm-project\lldb\test\Shell\Expr\TestGlobalSymbolObjCConflict.c
|
| -dump-input=help explains the following input dump.
|
| Input was:
| <<<<<<
| 1: (lldb) command source -s 0 'C:/buildbot/as-builder-10/lldb-x86-64/build/tools/lldb\test\Shell\lit-lldb-init-quiet'
| check:30'0 X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
| 2: Executing commands in 'C:\buildbot\as-builder-10\lldb-x86-64\build\tools\lldb\test\Shell\lit-lldb-init-quiet'.
| check:30'0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 3: (lldb) command source -C --silent-run true lit-lldb-init
| check:30'0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 4: (lldb) target create "C:\\buildbot\\as-builder-10\\lldb-x86-64\\build\\tools\\lldb\\test\\Shell\\Expr\\Output\\TestGlobalSymbolObjCConflict.c.tmp.out"
| check:30'0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| check:30'1 ? possible intended match
| 5: Current executable set to 'C:\buildbot\as-builder-10\lldb-x86-64\build\tools\lldb\test\Shell\Expr\Output\TestGlobalSymbolObjCConflict.c.tmp.out' (x86_64).
| check:30'0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 6: (lldb) b 27
| check:30'0 ~~~~~~~~~~~~
| >>>>>>
`-----------------------------
error: command failed with exit status: 1
```
We probably need to use LLD here or something. But I don't have a Windows machine to test this on. So XFAILing for now.
On Darwin C-symbols are prefixed with a '_'. The LLDB Macho-O parses
handles Objective-C metadata symbols starting with '_OBJC' specially.
Previously global symbols starting with a '_O' prefix were lost because
of incorrectly scoped if-guards. This patch removes those checks.
There is more cleanup that can be done in this file because there's a
bunch of duplicated checks for these ObjC symbols. I decided to leave
that for an NFC follow-up.
Depends on https://github.com/llvm/llvm-project/pull/161520
rdar://158159242
This patch works around an assertion that we hit in the `LambdaExpr`
constructor when we call it from `ASTNodeImporter::VisitLambdaExpr` (see
https://github.com/llvm/llvm-project/issues/149477). The lambda that we
imported doesn't have the `NumCaptures` field accurately set to the one
on the source decl. This is because in `MinimalImport` mode, we skip
importing of lambda definitions:
e21b0dd819/clang/lib/AST/ASTImporter.cpp (L2499)
In practice we have seen this assertion occur in our `import-std-module`
test-suite when libc++ headers decide to use lambdas inside inline
function bodies (the latest failure being caused by
https://github.com/llvm/llvm-project/pull/144602).
To avoid running into this whenever libc++ decides to use lambdas in
headers, this patch skips `ASTImport` of lambdas alltogether. Ideally
this would bubble up to the user or log as an error, but we swallow the
`ASTImportError`s currently. The only way this codepath is hit is when
lambdas are used inside functions in defined in the expression
evaluator, or when importing AST nodes from Clang modules. Both of these
are very niche use-cases (for now), so a workaround seemed appropriate.
Add test that checks whether the expression evaluator can handle
the `NS_ENUM`/`NS_OPTIONS` typedefs from Objective-C `CoreFoundation`.
In the test, `module.h` mimicks the `NS_OPTIONS` typedef from `CoreFoundation`.
The `ClangModulesDeclVendor` currently compiles modules as
C++, so the `MyInt` Clang decl in the module will be a `TypedefType`,
while the DWARF AST parser will produce an `EnumType` (since that's what
the debug-info says). When the `ASTImporter` imports these decls into the
scratch AST, it will fail to re-use one or the other decl because they
aren't structurally equivalent (one is a typedef, the other an enum),
so we end up with two conflicting `MyInt` declarations in the scratch AST
and the expression fails to run due to ambiguity in name lookup.
rdar://151022173
Failing on the Linux bots with:
```
+ /home/worker/2.0.1/lldb-x86_64-debian/build/bin/FileCheck /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/Shell/Expr/TestClangModulesDeclLookup.test
/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/Shell/Expr/TestClangModulesDeclLookup.test:56:15: error: CHECK-NEXT: expected string not found in input
^
<stdin>:38:26: note: scanning from here
(lldb) expression foo(50)
^
<stdin>:41:34: note: possible intended match here
(lldb) target modules dump ast --filter foo
^
```
Adds coverage for the code-path where
`ClangExpressionDeclMap::FindExternalVisibleDecls` finds a decl inside
of a Clang module (without explicitly having to import the module on the
LLDB CLI). AFAICT, we had not tests for this.
`LookupFunction` will try to find a `FunctionDecl` in debug-info. But if
no debug-info exists, it will ask the `ClangModulesDeclVendor` to search
for the function with the specified name in any of the Clang modules
that got added to it in `SetupDeclVendor`.
This reverts commit daa4061d61216456baa83ab404e096200e327fb4.
Original PR https://github.com/llvm/llvm-project/pull/129092.
I have restricted the test to X86 Windows because it turns out the only
reason that `expr x.get()` would change m_memory_id is that on x86 we
have to write the return address to the stack in ABIWindows_X86_64::PrepareTrivialCall:
```
// Save return address onto the stack
if (!process_sp->WritePointerToMemory(sp, return_addr, error))
return false;
```
This is not required on AArch64 so m_memory_id was not changed:
```
(lldb) expr x.get()
(int) $0 = 0
(lldb) process status -d
Process 15316 stopped
* thread #1, stop reason = Exception 0x80000003 encountered at address 0x7ff764a31034
frame #0: 0x00007ff764a31038 TestProcessModificationIdOnExpr.cpp.tmp`main at TestProcessModificationIdOnExpr.cpp:35
32 __builtin_debugtrap();
33 __builtin_debugtrap();
34 return 0;
-> 35 }
36
37 // CHECK-LABEL: process status -d
38 // CHECK: m_stop_id: 2
ProcessModID:
m_stop_id: 3
m_last_natural_stop_id: 0
m_resume_id: 0
m_memory_id: 0
```
Really we should find a better way to force a memory write here, but
I can't think of one right now.
And a follow up warning fix.
This reverts commit 6aa963f780d63d4c8fa80de97dd79c932bc35f4e
and 2bff80f25d51e24d3c552e033a2863dd36ef648b.
This is failing on Windows on Arm: https://lab.llvm.org/buildbot/#/builders/141/builds/8375
Seems to produce the line the test wants but not in the right place.
Reverting while I investigate.
This change adds a setting `target.process.track-memory-cache-changes`.
Disabling this setting prevents invalidating and updating values in
`ValueObject::UpdateValueIfNeeded` when only "internal" debugger memory
is updated. Writing to "internal" debugger memory happens when, for
instance, expressions are evaluated by visualizers (pretty printers).
One of the examples when cache invalidation has a particularly heavy
impact is visualizations of some collections: in some collections
getting collection size is an expensive operation (it requires traversal
of the collection).
At the same time evaluating user expression with side effects (visible
to target, not only to debugger) will still bump memory ID because:
- If expression is evaluated via interpreter: it will cause write to
"non-internal" memory
- If expression is JIT-compiled: then to call the function LLDB will
write to "non-internal" stack memory
The downside of disabled `target.process.track-memory-cache-changes`
setting is that convenience variables won't reevaluate synthetic
children automatically.
---------
Co-authored-by: Mikhail Zakharov <mikhail.zakharov@jetbrains.com>
This patch consumes the `DW_AT_APPLE_enum_kind` attribute added in
https://github.com/llvm/llvm-project/pull/124752 and turns it into a
Clang attribute in the AST. This will currently be used by the Swift
language plugin when it creates `EnumDecl`s from debug-info and passes
it to Swift compiler, which expects these attributes
This reverts commit 000febd0290698728abd9e23da6b27969c529177.
This is failing on the macOS public buildbots. It's unclear
to me why (I can't reproduce the failure on my local M1 machine).
I suspect the test might be relying on some non-deterministic
linker properties (such as order of entries in the debug-map
or something like that). The failure is as follows:
```
CHECK-NEXT: expected string not found in input
^
<stdin>:25:7: note: scanning from here
y = 2
^
<stdin>:27:4: note: possible intended match here
(lldb) exit
^
Input file: <stdin>
Check file: /Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/Shell/Expr/TestObjCHiddenIvars.test
-dump-input=help explains the following input dump.
Input was:
<<<<<<
.
.
.
20: (lldb) expression *f
21: (Foo) $0 = {
22: NSObject = {
23: isa = Foo
24: }
25: y = 2
next:21'0 X error: no match found
26: }
next:21'0 ~~
27: (lldb) exit
next:21'0 ~~~~~~~~~~~~
next:21'1 ? possible intended match
>>>>>>
```
When given a DIE for an Objective-C interface (which doesn't have a
`DW_AT_APPLE_objc_complete_type`), the `DWARFASTParserClang` will try to
find the DIE which corresponds to the implementation to complete the
interface DIE. The code is here:
d2e7ee77d3/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (L1718-L1738)
However, this was currently not exercised in our test-suite (removing
the code above didn't fail any LLDB test).
This patch adds a test which exercises this codepath (it will fail if we
don't fetch the implementation DIE in the `DWARFASTParserClang`).
Something that's not currently clear to me is why `frame var *f`
succeeds even without the `DW_AT_APPLE_objc_complete_type`
infrastructure. If it's using the ObjC runtime, we should make `expr` do
the same, in which case we can remove this code from
`DWARFASTParserClang`.
Expressions can take arbitrary amounts of time to run, so IDEs might
want to be informed about the fact that an expression is currently being
executed.
rdar://141253078
Since the remote Shell test execution feature was added, these tests
should now be disabled on Windows target instead of Windows host.
It should fix failures on
https://lab.llvm.org/staging/#/builders/197/builds/76.
1. This commit adds LLDB_TEST_PLATFORM_URL, LLDB_TEST_SYSROOT,
LLDB_TEST_PLATFORM_WORKING_DIR, LLDB_SHELL_TESTS_DISABLE_REMOTE cmake
flags to pass arguments for cross-compilation and remote running of both Shell&API tests.
2. To run Shell tests remotely, it adds 'platform select' and 'platform connect' commands to %lldb
substitution.
3. 'remote-linux' feature added to lit to disable tests failing with
remote execution.
4. A separate working directory is assigned to each test to avoid
conflicts during parallel test execution.
5. Remote Shell testing is run only when LLDB_TEST_SYSROOT is set for
building test sources. The recommended compiler for that is Clang.
---------
Co-authored-by: Vladimir Vereschaka <vvereschaka@accesssoftek.com>
This patch is a reworking of Pete Lawrence's (@PortalPete) proposal
for better expression evaluator error messages:
https://github.com/llvm/llvm-project/pull/80938
Before:
```
$ lldb -o "expr a+b"
(lldb) expr a+b
error: <user expression 0>:1:1: use of undeclared identifier 'a'
a+b
^
error: <user expression 0>:1:3: use of undeclared identifier 'b'
a+b
^
```
After:
```
(lldb) expr a+b
^ ^
│ ╰─ error: use of undeclared identifier 'b'
╰─ error: use of undeclared identifier 'a'
```
This eliminates the confusing `<user expression 0>:1:3` source
location and avoids echoing the expression to the console again, which
results in a cleaner presentation that makes it easier to grasp what's
going on. You can't see it here, bug the word "error" is now also in
color, if so desired.
Depends on https://github.com/llvm/llvm-project/pull/106442.
This patch is a reworking of Pete Lawrence's (@PortalPete) proposal
for better expression evaluator error messages:
https://github.com/llvm/llvm-project/pull/80938
Before:
```
$ lldb -o "expr a+b"
(lldb) expr a+b
error: <user expression 0>:1:1: use of undeclared identifier 'a'
a+b
^
error: <user expression 0>:1:3: use of undeclared identifier 'b'
a+b
^
```
After:
```
(lldb) expr a+b
^ ^
│ ╰─ error: use of undeclared identifier 'b'
╰─ error: use of undeclared identifier 'a'
```
This eliminates the confusing `<user expression 0>:1:3` source
location and avoids echoing the expression to the console again, which
results in a cleaner presentation that makes it easier to grasp what's
going on. You can't see it here, bug the word "error" is now also in
color, if so desired.
Depends on https://github.com/llvm/llvm-project/pull/106442.
This recently added test is failing on Windows with:
```
c:\users\tcwg\llvm-worker\lldb-aarch64-windows\build\bin\lldb.exe --no-lldbinit -S C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/tools/lldb\test\Shell\lit-lldb-init-quiet C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\test\Shell\Expr\Output\TestAnonNamespaceParamFunc.cpp.tmp -o run -o "expression func(a)" -o exit | c:\users\tcwg\llvm-worker\lldb-aarch64-windows\build\bin\filecheck.exe C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\Shell\Expr\TestAnonNamespaceParamFunc.cpp
executed command: 'c:\users\tcwg\llvm-worker\lldb-aarch64-windows\build\bin\lldb.exe' --no-lldbinit -S 'C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/tools/lldb\test\Shell\lit-lldb-init-quiet' 'C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\test\Shell\Expr\Output\TestAnonNamespaceParamFunc.cpp.tmp' -o run -o 'expression func(a)' -o exit
.---command stderr------------
| TestAnonNamespaceParamFunc.cpp.tmp :: Class 'tagARRAYDESC' has a member 'tdescElem' of type 'tagTYPEDESC' which does not have a complete definition.error: TestAnonNamespaceParamFunc.cpp.tmp :: Class 'tagARRAYDESC' has a member 'tdescElem' of type 'tagTYPEDESC' which does not have a complete definition.
| (lldb) TestAnonNamespaceParamFunc.cpp.tmp :: Class 'std::partial_ordering' has a member 'less' of type 'std::partial_ordering' which does not have a complete definition.error: TestAnonNamespaceParamFunc.cpp.tmp :: Class 'std::partial_ordering' has a member 'less' of type 'std::partial_ordering' which does not have a complete definition.
| (lldb) TestAnonNamespaceParamFunc.cpp.tmp :: Class 'std::strong_ordering' has a member 'less' of type 'std::strong_ordering' which does not have a complete definition.error: TestAnonNamespaceParamFunc.cpp.tmp :: Class 'std::strong_ordering' has a member 'less' of type 'std::strong_ordering' which does not have a complete definition.
| (lldb) TestAnonNamespaceParamFunc.cpp.tmp :: Class 'std::weak_ordering' has a member 'less' of type 'std::weak_ordering' which does not have a complete definition.error: TestAnonNamespaceParamFunc.cpp.tmp :: Class 'std::weak_ordering' has a member 'less' of type 'std::weak_ordering' which does not have a complete definition.
| (lldb) error: Couldn't look up symbols:
| int func(struct `anonymous namespace'::InAnon)
| Hint: The expression tried to call a function that is not present in the target, perhaps because it was optimized out by the compiler.
`-----------------------------
executed command: 'c:\users\tcwg\llvm-worker\lldb-aarch64-windows\build\bin\filecheck.exe' 'C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\Shell\Expr\TestAnonNamespaceParamFunc.cpp'
.---command stderr------------
| C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\Shell\Expr\TestAnonNamespaceParamFunc.cpp:10:11: error: CHECK: expected string not found in input
| // CHECK: (int) $0 = 15
| ^
| <stdin>:16:26: note: scanning from here
| (lldb) expression func(a)
| ^
```
So the function is still not callable. But AFAICT, this is not a
regression, since this function wasn't callable prior to the patch
anyway. I currently do not have a Windows setup to test this on,
so XFAIL for now.
While parsing an expression, Clang tries to diagnose usage of decls
(with possibly non-external linkage) for which it hasn't been provided
with a definition. This is the case, e.g., for functions with parameters
that live in an anonymous namespace (those will have `UniqueExternal`
linkage, this is computed [here in
computeTypeLinkageInfo](ea8bb4d633/clang/lib/AST/Type.cpp (L4647-L4653))).
Before diagnosing such situations, Clang calls
`ExternalSemaSource::ReadUndefinedButUsed`. The intended use of this API
is to extend the set of "used but not defined" decls with additional
ones that the external source knows about. However, in LLDB's case, we
never provide `FunctionDecl`s with a definition, and instead rely on the
expression parser to resolve those symbols by linkage name. Thus, to
avoid the Clang parser from erroring out in these situations, this patch
implements `ReadUndefinedButUsed` which just removes the "undefined"
non-external `FunctionDecl`s that Clang found.
We also had to add an `ExternalSemaSource` to the `clang::Sema` instance
LLDB creates. We previously didn't have any source on `Sema`. Because we
add the `ExternalASTSourceWrapper` here, that means we'd also
technically be adding the `ClangExpressionDeclMap` as an
`ExternalASTSource` to `Sema`, which is fine because `Sema` will only be
calling into the `ExternalSemaSource` APIs (though nothing currently
strictly enforces this, which is a bit worrying).
Note, the decision for whether to put a function into `UndefinedButUsed`
is done in
[Sema::MarkFunctionReferenced](ea8bb4d633/clang/lib/Sema/SemaExpr.cpp (L18083-L18087)).
The `UniqueExternal` linkage computation is done in
[getLVForNamespaceScopeDecl](ea8bb4d633/clang/lib/AST/Decl.cpp (L821-L833)).
Fixes https://github.com/llvm/llvm-project/issues/104712
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 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
After https://github.com/llvm/llvm-project/pull/68052 this function changed from returning
a nullptr with `return {};` to returning Expected and hitting `llvm_unreachable` before it could
do so.
I gather that we're never supposed to call this function, but on Windows we actually do call
this function because `interpreter->CreateScriptedProcessInterface()` returns
`ScriptedProcessInterface` not `ScriptedProcessPythonInterface`. Likely because
`target_sp->GetDebugger().GetScriptInterpreter()` also does not return a Python related class.
The previously XFAILed test crashed with:
```
# .---command stderr------------
# | PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
# | Stack dump:
# | 0. Program arguments: c:\\users\\tcwg\\david.spickett\\build-llvm\\bin\\lldb-test.exe ir-memory-map C:\\Users\\tcwg\\david.spickett\\build-llvm\\tools\\lldb\\test\\Shell\\Expr\\Output\\TestIRMemoryMapWindows.test.tmp C:\\Users\\tcwg\\david.spickett\\llvm-project\\lldb\\test\\Shell\\Expr/Inputs/ir-memory-map-basic
# | 1. HandleCommand(command = "run")
# | Exception Code: 0xC000001D
# | #0 0x00007ff696b5f588 lldb_private::ScriptedProcessInterface::CreatePluginObject(class llvm::StringRef, class lldb_private::ExecutionContext &, class std::shared_ptr<class lldb_private::StructuredData::Dictionary>, class lldb_private::StructuredData::Generic *) C:\Users\tcwg\david.spickett\llvm-project\lldb\include\lldb\Interpreter\Interfaces\ScriptedProcessInterface.h:28:0
# | #1 0x00007ff696b1d808 llvm::Expected<std::shared_ptr<lldb_private::StructuredData::Generic> >::operator bool C:\Users\tcwg\david.spickett\llvm-project\llvm\include\llvm\Support\Error.h:567:0
# | #2 0x00007ff696b1d808 lldb_private::ScriptedProcess::ScriptedProcess(class std::shared_ptr<class lldb_private::Target>, class std::shared_ptr<class lldb_private::Listener>, class lldb_private::ScriptedMetadata const &, class lldb_private::Status &) C:\Users\tcwg\david.spickett\llvm-project\lldb\source\Plugins\Process\scripted\ScriptedProcess.cpp:115:0
# | #3 0x00007ff696b1d124 std::shared_ptr<lldb_private::ScriptedProcess>::shared_ptr C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1478:0
# | #4 0x00007ff696b1d124 lldb_private::ScriptedProcess::CreateInstance(class std::shared_ptr<class lldb_private::Target>, class std::shared_ptr<class lldb_private::Listener>, class lldb_private::FileSpec const *, bool) C:\Users\tcwg\david.spickett\llvm-project\lldb\source\Plugins\Process\scripted\ScriptedProcess.cpp:61:0
# | #5 0x00007ff69699c8f4 std::_Ptr_base<lldb_private::Process>::_Move_construct_from C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1237:0
# | #6 0x00007ff69699c8f4 std::shared_ptr<lldb_private::Process>::shared_ptr C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1534:0
# | #7 0x00007ff69699c8f4 std::shared_ptr<lldb_private::Process>::operator= C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1594:0
# | #8 0x00007ff69699c8f4 lldb_private::Process::FindPlugin(class std::shared_ptr<class lldb_private::Target>, class llvm::StringRef, class std::shared_ptr<class lldb_private::Listener>, class lldb_private::FileSpec const *, bool) C:\Users\tcwg\david.spickett\llvm-project\lldb\source\Target\Process.cpp:396:0
# | #9 0x00007ff6969bd708 std::_Ptr_base<lldb_private::Process>::_Move_construct_from C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1237:0
# | #10 0x00007ff6969bd708 std::shared_ptr<lldb_private::Process>::shared_ptr C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1534:0
# | #11 0x00007ff6969bd708 std::shared_ptr<lldb_private::Process>::operator= C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1594:0
# | #12 0x00007ff6969bd708 lldb_private::Target::CreateProcess(class std::shared_ptr<class lldb_private::Listener>, class llvm::StringRef, class lldb_private::FileSpec const *, bool) C:\Users\tcwg\david.spickett\llvm-project\lldb\source\Target\Target.cpp:215:0
# | #13 0x00007ff696b13af0 std::_Ptr_base<lldb_private::Process>::_Ptr_base C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1230:0
# | #14 0x00007ff696b13af0 std::shared_ptr<lldb_private::Process>::shared_ptr C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1524:0
# | #15 0x00007ff696b13af0 lldb_private::PlatformWindows::DebugProcess(class lldb_private::ProcessLaunchInfo &, class lldb_private::Debugger &, class lldb_private::Target &, class lldb_private::Status &) C:\Users\tcwg\david.spickett\llvm-project\lldb\source\Plugins\Platform\Windows\PlatformWindows.cpp:495:0
# | #16 0x00007ff6969cf590 std::_Ptr_base<lldb_private::Process>::_Move_construct_from C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1237:0
# | #17 0x00007ff6969cf590 std::shared_ptr<lldb_private::Process>::shared_ptr C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1534:0
# | #18 0x00007ff6969cf590 std::shared_ptr<lldb_private::Process>::operator= C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.35.32124\include\memory:1594:0
# | #19 0x00007ff6969cf590 lldb_private::Target::Launch(class lldb_private::ProcessLaunchInfo &, class lldb_private::Stream *) C:\Users\tcwg\david.spickett\llvm-project\lldb\source\Target\Target.cpp:3274:0
# | #20 0x00007ff696fff82c CommandObjectProcessLaunch::DoExecute(class lldb_private::Args &, class lldb_private::CommandReturnObject &) C:\Users\tcwg\david.spickett\llvm-project\lldb\source\Commands\CommandObjectProcess.cpp:258:0
# | #21 0x00007ff696fab6c0 lldb_private::CommandObjectParsed::Execute(char const *, class lldb_private::CommandReturnObject &) C:\Users\tcwg\david.spickett\llvm-project\lldb\source\Interpreter\CommandObject.cpp:751:0
# `-----------------------------
# error: command failed with exit status: 0xc000001d
```
That might be a bug on the Windows side, or an artifact of how our build is setup,
but whatever it is, having `CreatePluginObject` return an error and
the caller check it, fixes the failing test.
The built lldb can run the script command to use Python, but I'm not sure if that means
anything.
When trying to run an expression after a process has existed, you
currently are shown the following error message:
(lldb) p strlen("")
error: Can't make a function caller while the process is running
This error is wrong and pretty uninformative. After this patch, the
following error message is shown:
(lldb) p strlen("")
error: unable to evaluate expression while the process is exited: the
process must be stopped because the expression might require
allocating memory.
rdar://109731325
Differential revision: https://reviews.llvm.org/D151497
This is the next patch after D146058. We can now parse expressions to print instance variables from ObjC classes. Until now the expression parser would bail out with an error like this:
```
error: expression failed to parse:
error: Error [IRForTarget]: Couldn't find Objective-C indirect ivar symbol OBJC_IVAR_$_TestObj._int
```
Reviewed By: aprantl
Differential Revision: https://reviews.llvm.org/D146154
This patch adds test infrastructure to utilize the GNUstep runtime in the LLDB test suite and adds coverage for features that already work on Linux. These seem accidental in parts, but it's a good early baseline. On Windows nothing works yet. Please find the repository for the GNUstep ObjC runtime here: https://github.com/gnustep/libobjc2
GNUstep support is disabled by default. CMake configuration involves two variables:
* `LLDB_TEST_OBJC_GNUSTEP=On` enables GNUstep support in the test suite. It requires the libobjc2 shared library and headers to be found.
* `LLDB_TEST_OBJC_GNUSTEP=Off` disables GNUstep support in the test suite and resets associated cache values if necessary (default).
* `LLDB_TEST_OBJC_GNUSTEP_DIR` allows to pass a custom installation root.
Differential Revision: https://reviews.llvm.org/D146058
In Shell tests, replace use of the `p` alias with the `expression` command.
To avoid conflating tests of the alias with tests of the expression command,
this patch canonicalizes to the use `expression`.
See also D141539 which made the same change to API tests.
Differential Revision: https://reviews.llvm.org/D146230
This test should exercise the usage of expressions containing
string literals and ensure that lldb doesn't crash.
Differential Revision: https://reviews.llvm.org/D129261
Some LD_PRELOAD-ed libraries tend to interact badly with --nodefaultlib,
particularly Gentoo sandbox. Do not run this test if LD_PRELOAD is
present in the running environment.
Differential Revision: https://reviews.llvm.org/D107701
XFAIL nodefaultlib.cpp on darwin - the test does not pass there
XFAIL TestGdbRemoteMemoryAllocation on windows - memory is allocated
with incorrect permissions
This patch adds support for the _M and _m gdb-remote packets, which
(de)allocate memory in the inferior. This works by "injecting" a
m(un)map syscall into the inferior. This consists of:
- finding an executable page of memory
- writing the syscall opcode to it
- setting up registers according to the os syscall convention
- single stepping over the syscall
The advantage of this approach over calling the mmap function is that
this works even in case the mmap function is buggy or unavailable. The
disadvantage is it is more platform-dependent, which is why this patch
only works on X86 (_32 and _64) right now. Adding support for other
linux architectures should be easy and consist of defining the
appropriate syscall constants. Adding support for other OSes depends on
the its ability to do a similar trick.
Differential Revision: https://reviews.llvm.org/D89124
Summary:
Currently expect_expr will not run the expression if no target is selected. This
patch changes this behavior so that expect_expr will instead fall back to the
dummy target similar to what the `expression` command is doing. This way we
don't have to compile an empty executable to be able to use `expect_expr` (which
is a waste of resources for tests that just test generic type system features).
As a test I modernized the TestTypeOfDeclTypeExpr into a Python test +
expect_expr (as it relied on the dummy target fallback of the expression
command).
Reviewers: labath, JDevlieghere
Reviewed By: labath
Subscribers: abidh
Differential Revision: https://reviews.llvm.org/D83388