Types that came from a Clang module are nested in DW_TAG_module tags
in DWARF. This patch recreates the Clang module hierarchy in LLDB and
1;95;0csets the owning module information accordingly. My primary motivation
is to facilitate looking up per-module APINotes for individual
declarations, but this likely also has other applications.
This reapplies the previously reverted commit, but without support for
ClassTemplateSpecializations, which I'm going to look into separately.
rdar://problem/59634380
Differential Revision: https://reviews.llvm.org/D75488
Add a small artificial delay in replay mode before exiting to ensure
that all asynchronous events have completed. This should reduce the
level of replay flakiness on some of the slower bots.
The synchronization logic in the previous had a subtle bug. Moving of
the "m_read_thread_did_exit = true" into the critical section made it
possible for some threads calling SynchronizeWithReadThread call to get
stuck. This could happen if there were already past the point where they
checked this variable. In that case, they would block on waiting for the
eBroadcastBitNoMorePendingInput event, which would never come as the
read thread was blocked on getting the synchronization mutex.
The new version moves that line out of the critical section and before
the sending of the eBroadcastBitNoMorePendingInput event, and also adds
some comments to explain why the things need to be in this sequence:
- m_read_thread_did_exit = true: prevents new threads for waiting on
events
- eBroadcastBitNoMorePendingInput: unblock any current thread waiting
for the event
- Disconnect(): close the connection. This is the only bit that needs to
be in the critical section, and this is to ensure that we don't close
the connection while the synchronizing thread is mucking with it.
Original commit message follows:
Communication::SynchronizeWithReadThread is called whenever a process
stops to ensure that we process all of its stdout before we report the
stop. If the process exits, we first call this method, and then close
the connection.
However, when the child process exits, the thread reading its stdout
will usually (but not always) read an EOF because the other end of the
pty has been closed. In response to an EOF, the Communication read
thread closes it's end of the connection too.
This can result in a race where the read thread is closing the
connection while the synchronizing thread is attempting to get its
attention via Connection::InterruptRead.
The fix is to hold the synchronization mutex while closing the
connection.
I've found this issue while tracking down a rare flake in some of the
vscode tests. I am not sure this is the cause of those failures (as I
would have expected this issue to manifest itself differently), but it
is an issue nonetheless.
The attached test demonstrates the steps needed to reproduce the race.
It will fail under tsan without this patch.
Reviewers: clayborg, JDevlieghere
Subscribers: mgorny, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77295
Summary:
Communication::SynchronizeWithReadThread is called whenever a process
stops to ensure that we process all of its stdout before we report the
stop. If the process exits, we first call this method, and then close
the connection.
However, when the child process exits, the thread reading its stdout
will usually (but not always) read an EOF because the other end of the
pty has been closed. In response to an EOF, the Communication read
thread closes it's end of the connection too.
This can result in a race where the read thread is closing the
connection while the synchronizing thread is attempting to get its
attention via Connection::InterruptRead.
The fix is to hold the synchronization mutex while closing the
connection.
I've found this issue while tracking down a rare flake in some of the
vscode tests. I am not sure this is the cause of those failures (as I
would have expected this issue to manifest itself differently), but it
is an issue nonetheless.
The attached test demonstrates the steps needed to reproduce the race.
It will fail under tsan without this patch.
Reviewers: clayborg, JDevlieghere
Subscribers: mgorny, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77295
I fixed the bug that the "log timer" has no tab command.
Original code has the only CommandObjectLogTimer class, but it is not
sufficient. Thus I divided the content of CommandObjectLog class into
CommandObjectLogEnable class, CommandObjectLogDisable class,
CommandObjectLogDump class, CommandObjectLogReset class,
CommandObjectLogIncrement class.
Reviewed by: teemperor
Differential Revision: https://reviews.llvm.org/D76906
Using the approach suggested by Pavel in D77588, this patch introduces a
new lldbconfig module that lives next to the lldb module. It makes it
possible to make the lldb module configurable before importing it. More
specifically it makes it possible to delay initializing the debugger,
which is needed for testing the reproducer.
Differential revision: https://reviews.llvm.org/D77661
Summary:
This adds support for commands created through the API to support autorepeat.
This covers the case of single word and multiword commands.
Comprehensive tests are included as well.
Reviewers: labath, clayborg
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77444
Summary:
When using source maps for a breakpoint, in order to find the actual source that breakpoint has resolved, we
need to use a query similar to what CommandObjectSource::DumpLinesInSymbolContexts does, which is the logic
used by the CLI to display the source line at a given breakpoint. That's necessary because from a breakpoint
location you only have an address, which points to the original source location, not the source mapped one.
in the setBreakpoints request handler, we haven't been doing such query and we were returning the original
source location, which was breaking the UX of VSCode, as many breakpoints were being set but not displayed
in the source file next to each line. Besides, clicking the source path of a breakpoint in the breakpoints
view in the debug tab was not working for this case, as VSCode was trying to open a non-existent file, thus
showing an error to the user.
Ideally, we should do the query mentioned above to find the actual source location to respond to the IDE,
however, that query is expensive and users can have an arbitrary number of breakpoints set. As a simpler fix,
the request sent by VSCode already contains the full source path, which exists because the user set it from
the IDE itself, so we can simply reuse it instead of querying from the SB API.
I wrote a test for this, and found out that I had to move SetSourceMapFromArguments after RunInitCommands in
lldb-vscode.cpp, because an init command used in all tests is `settings clear -all`, which would clear the
source map unless specified after initCommands. And in any case, I think it makes sense to have initCommands
run before anything the debugger would do.
Reviewers: clayborg, kusmour, labath, aadsm
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D76968
Summary:
The buffer protocol does not allow us to just call PyBuffer_Release
and assume the buffer will still be there. Most things that implement the
buffer protocol will let us get away with that, but not all. We need
to release it at the end of the SWIG wrapper.
Reviewers: labath, jasonmolenda, JDevlieghere, vadimcn
Reviewed By: labath
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77480
Discussed on lldb-dev with Pavel Labath. This doesn't work for
background processes [causes Python to be stuck forever], and it's
unclear whether it's needed. There's no test, also. If this turns
out to be useful, it can be recommitted with a functional implementation
and a test.
My main work directory is on a separate partition, but I usually access
it through a symlink in my home directory. When running the tests,
either Clang or make resolves the symlink, and the real path of the
test directory ends up in the debug information.
This confuses this test as LLDB is trying to remap the real path, but
the remapping description uses the path with the symlink in
it. Calling realpath on the source path when constructing the
remapping description fixes it.
We would return `LLDB_INVALID_IMAGE_TOKEN` for the address rather than
the correct value of `LLDB_IMAGE_ADDRESS`. This would result in the
check for the return value to silently pass on x64 as the invalid
address and invalid token are of different sizes (`size_t` vs
`uintprr_t`). This corrects the return value to `LLDB_INVALID_ADDRESS`
and addresses the rest to reset the mapped address to the invalid value.
This was found by inspection when trying to implement module support for
Windows.
This is mostly useful for Swift support; it allows LLDB to substitute
a matching SDK it shipped with instead of the sysroot path that was
used at compile time.
The goal of this is to make the Xcode SDK something that behaves more
like the compiler's resource directory, as in that it ships with LLDB
rather than with the debugged program. This important primarily for
importing Swift and Clang modules in the expression evaluator, and
getting at the APINotes from the SDK in Swift.
For a cross-debugging scenario, this means you have to have an SDK for
your target installed alongside LLDB. In Xcode this will always be the
case.
rdar://problem/60640017
Differential Revision: https://reviews.llvm.org/D76471
Greg Clayton a few years ago.
My patch to augment the symbol table in Mach-O files with the
dyld trie exports data structure only categorized symbols as code
or data, but Greg Clayton had a patch to do something similar to
swift a few years ago that had a more extensive categorization of
symbols, as well as extracting some objc class/ivar names from the
entries. This patch is basically just Greg's, updated a bit and
with a test case added to it.
<rdar://problem/50791451>
Differential Revision: https://reviews.llvm.org/D77369
This patch adds parts of the stack that should be useful for unwinding
to the jThreadsInfo reply from lldb-server. We return the top of the
stack (12 words), and we also try to walk the frame pointer linked list
and return the memory containing frame pointer and return address pairs.
The idea is to cover the cases with and without frame pointer omission.
Differential Revision: https://reviews.llvm.org/D74398
Summary:
Usually when Clang emits an error Fix-It it does two things. It emits the diagnostic and then it fixes the
currently generated AST to reflect the applied Fix-It. While emitting the diagnostic is easy to implement,
fixing the currently generated AST is often tricky. That causes that some Fix-Its just keep the AST as-is or
abort the parsing process entirely. Once the parser stopped, any Fix-Its for the rest of the expression are
not detected and when the user manually applies the Fix-It, the next expression will just produce a new
Fix-It.
This is often occurring with quickly made Fix-Its that are just used to bridge temporary API changes
and that often are not worth implementing a proper API fixup in addition to the diagnostic. To still
give some kind of reasonable user-experience for users that have these Fix-Its and rely on them to
fix their expressions, this patch adds the ability to retry parsing with applied Fix-Its multiple time to
give the normal Fix-It experience where things Clang knows how to fix are not causing actual expression
error (at least when automatically applying Fix-Its is activated).
The way this is implemented is just by having another setting in the expression options that specify how
often we should try applying Fix-Its and then reparse the expression. The default setting is still 1 for everyone
so this should not affect the speed in which we fail to parse expressions.
Reviewers: jingham, JDevlieghere, friss, shafik
Reviewed By: shafik
Subscribers: shafik, abidh
Differential Revision: https://reviews.llvm.org/D77214
Summary:
LLDB currently applies Fix-Its if they are attached to a Clang diagnostic that has the
severity "error". Fix-Its connected to warnings and other severities are supposed to
be ignored as LLDB doesn't seem to trust Clang Fix-Its in these situations.
However, LLDB also ignores all Fix-Its coming from "note:" diagnostics. These diagnostics
are usually emitted alongside other diagnostics (both warnings and errors), either to keep
a single diagnostic message shorter or because the Fix-It is in a different source line. As they
are technically their own (non-error) diagnostics, we currently are ignoring all Fix-Its associated with them.
For example, this is a possible Clang diagnostic with a Fix-It that is currently ignored:
```
error: <user expression 1>:2:10: too many arguments provided to function-like macro invocation
ToStr(0, {,})
^
<user expression 1>:1:9: macro 'ToStr' defined here
#define ToStr(x) #x
^
<user expression 1>:2:1: cannot use initializer list at the beginning of a macro argument
ToStr(0, {,})
^ ~~~~
```
We also don't store "note:" diagnostics at all, as LLDB's abstraction around the whole diagnostic
concept doesn't have such a concept. The text of "note:" diagnostics is instead
appended to the last non-note diagnostic (which is causing that there is no "note:" text in the
diagnostic above, as all the "note:" diagnostics have been appended to the first "error: ..." text).
This patch fixes the ignored Fix-Its in note-diagnostics by appending them to the last non-note
diagnostic, similar to the way we handle the text in these diagnostics.
Reviewers: JDevlieghere, jingham
Reviewed By: JDevlieghere
Subscribers: abidh
Differential Revision: https://reviews.llvm.org/D77055
This is a preparation for an upcoming patch which adds support for
DWARFv5 unit index sections. The patch adds tag "_EXT_" to identifiers
which reference sections that are deprecated in the DWARFv5 standard.
See D75929 for the discussion.
Differential Revision: https://reviews.llvm.org/D77141
Mark it expected fail for now.
The test output shows that the "internal" thread listing isn't showing the
step out plan that we use to step back out of a function we're stepping into.
The internal plan listing code has nothing platform specific in it, so that
isn't the problem.
I am pretty sure the difference is that on MacOS we step into the function and then need to
step back out again so we push the internal plan the test is checking for. But on Linux we
are able to step past the function without stepping into it.
So nothing is actually going wrong here, I just need to find a better test case where I
can ensure we are going to have to push a private plan. It's probably better to test this
using a custom thread plan, then I can control the state of the plan stack better.
That's for Monday...
Summary:
A recent change in ThreadPlans introduced this little compilation error.
Seems to be related to the work around https://reviews.llvm.org/D76814.
Reviewers: clayborg, labath, jingham
Reviewed By: jingham
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77450
Summary:
In this diff of mine D77186 I introduce a bug in the replace operation, where I was failing fast by mistake.
Besides, a similar problem existed in the insert-after operation, where it was failing fast.
Finally, the remove operation was wrong, as it was not using the indices provided by the users.
I fixed those issues and added some tests account for cases with multiple elements in these requests.
Reviewers: labath, clayborg
Reviewed By: labath
Subscribers: mgrang, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77324
Summary:
@labath mentioned to me that test files shouldn't have a license header.
I saw this one some days ago, so I'm doing some cleaning.
Reviewers: labath, clayborg
Subscribers: lldb-commits, labath
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77328
Also turn on the command trace unconditionally for TestThreadPlanCommands.py as the
tests for the Ubuntu bot don't seem to run with -t making it hard to see why this is
failing remotely.
Apparently the intention was to copy the condition above:
if (types.GetSize() >= max_matches)
break;
So that if the iteration stopped because of too many matches we do not
add even more matches in this 'Clang modules' block downward.
It was implemented by:
SymbolFileDWARF: Unconditionally scan through clang modules. NFCish
fe9eaadd68
Differential Revision: https://reviews.llvm.org/D77336
that were not reported by the OS plugin. To facilitate this, move
adding/updating the ThreadPlans for a Thread to the ThreadPlanStackMap.
Also move dumping thread plans there as well.
Added some tests for "thread plan list" and "thread plan discard" since
I didn't seem to have written any originally.
Differential Revision: https://reviews.llvm.org/D76814
It is an obvious part of D77326.
It removes some needless deep indentation and some redundant statements.
It prepares the code for a more clean next patch - DWARF index callbacks
in D77327.
LLDB relies on empty FileSpecs being invalid files, for example, they
don't exists. Currently this assumption does not always hold during
reproducer replay, because we pass the result of GetPath to the VFS.
This is an empty string, which the VFS converts to an absolute directory
by prepending the current working directory, before looking it up in the
YAML mapping. This means that an empty FileSpec will exist when the
current working directory does. This breaks at least one test
(TestAddDsymCommand.py) when ran from replay.
This patch special cases empty FileSpecs and returns a sensible result
before calling GetPath and forwarding the call.
Differential revision: https://reviews.llvm.org/D77351
This reimplements Symbols::FindSymbolFileInBundle to use the VFS-aware
recursive directory iterator. This is needed for reproducer replay.
Differential revision: https://reviews.llvm.org/D77337
The old name was a bit misleading because the functions actually return
contributions to the corresponding sections.
Differential revision: https://reviews.llvm.org/D77302
Summary: The IDE has no packets that are sent to lldb-vscode that say which thread and frame are selected. The only way we know is we get a request for variables for a stack frame via a "scopes" request. When we receive this packet we make that thread and frame the selected thread and frame in lldb. This way when people execute lldb commands in the debug console by prefixing the expression with the backtick character, we will have the right thread and frame selected. Previously this was not updated as new stack frames were selected.
Reviewers: labath, aadsm, wallace, JDevlieghere
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77347
* This is a reattempted commit due to a previous builtbot failure
- Now using a env var to determine whether to run the test, as
someone might have built liblldbIntelFeatures.so without intelPT
support, which would make this test fail.
Summary:
Depends on D76872.
There was no test for the Intel PT support on LLDB, so I'm creating one, which
will help making progress on solid grounds.
The test is skipped if the Intel PT plugin library is not built.
Reviewers: clayborg, labath, kusmour, aadsm
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77107
--script-language python and --script-language lua are both valid now.
Reviewed by: JDevlieghere
Differential Revision: https://reviews.llvm.org/D77241
This patch was reverted because it introduced a failure in
TestHelloWorld.py. The reason for that was running "ls" shell command
failed as it was evaluated in an environment with an empty path. This
has now been fixed with D77123, which ensures that all shell commands
inherit the host environment, so this patch should be safe to recommit.
The original commit message was:
A defensive check in ProcessLauncherWindows meant that we would never
attempt to launch a process with a completely empty environment -- the
host environment would be used instead. Instead, I make the function add
an extra null wchar_t at the end of an empty environment. The
documentation on this is a bit fuzzy, but it seems to be what is needed
to make windows accept these kinds of environments.
Reviewers: amccarth, friss
Differential Revision: https://reviews.llvm.org/D76835
Types that came from a Clang module are nested in DW_TAG_module tags
in DWARF. This patch recreates the Clang module hierarchy in LLDB and
sets the owning module information accordingly. My primary motivation
is to facilitate looking up per-module APINotes for individual
declarations, but this likely also has other applications.
rdar://problem/59634380
Differential Revision: https://reviews.llvm.org/D75488
Previously, this was reverted in bf65f19b becuase it checked whether
TARGET_OS_EMBEDDED is defined, but that macro is always defined.
Update the condition to check that TARGET_OS_OSX is true.
Summary:
Depends on D76872.
There was no test for the Intel PT support on LLDB, so I'm creating one, which
will help making progress on solid grounds.
The test is skipped if the Intel PT plugin library is not built.
Reviewers: clayborg, labath, kusmour, aadsm
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77107
Summary:
Depends on D76872.
There was no test for the Intel PT support on LLDB, so I'm creating one, which
will help making progress on solid grounds.
The test is skipped if the Intel PT plugin library is not built.
Reviewers: clayborg, labath, kusmour, aadsm
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77107
Summary:
Several lldb-vscode users have noticed that when a source map rule is invalid (because a folder doesn't exist anymore), the rest of the source maps from their configurations are not applied.
This happens because lldb-vscode executes a single "settings set target.source-map" command with all the source maps and LLDB processes them one by one until one fails.
Instead of doing this, we can process in LLDB all the source map rules and apply the valid ones instead of failing fast.
Reviewers: clayborg, labath, kusmour, aadsm
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77186
The RuntimeFunction struct, which PECallFrameInfo interprets, has a
different layout and differnet semantics on all architectures.
Differential Revision: https://reviews.llvm.org/D77000
Summary:
On most hosts we were running shell commands with an empty environment.
The only exception was windows, which was inheriting the host enviroment
mostly by accident.
Running the commands in an empty environment does not sound like a
sensible default, so this patch changes Host::RunShellCommand to inherit
the host environment. This impacts both commands run via
SBPlatform::Run (in case of host platforms), as well as the "platform
shell" CLI command.
Reviewers: jingham, friss
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D77123
Summary:
If we don't have a current frame then we can still run many expressions
as long as we have an active target. With this patch `expect_expr` directly
calls the target's EvaluateExpression function when there is no current frame.
Reviewers: labath
Reviewed By: labath
Subscribers: JDevlieghere
Differential Revision: https://reviews.llvm.org/D77197
The FileCollector in LLDB collects every files that's used during a
debug session when capture is enabled. This ensures that the reproducer
only contains the files necessary to reproduce. This approach is not a
good fit for the dSYM bundle, which is a directory on disk, but should
be treated as a single unit.
On macOS LLDB have automatically find the matching dSYM for a binary by
its UUID. Having a incomplete dSYM in a reproducer can break debugging
even when reproducers are disabled.
This patch adds a was to specify a directory of interest to the
reproducers. It is called from SymbolVendorMacOSX with the path of the
dSYMs used by LLDB.
Differential revision: https://reviews.llvm.org/D76672
Summary:
//reviews.llvm.org/D33035 added in 2017 basic support for intel-pt. I
plan to improve it and use it to support reverse debugging.
I fixed a couple of issues and now this plugin works again:
1. pythonlib needed to be linked against it for the SB framework.
Linking was failing because of this
2. the decoding functionality was broken because it lacked handling for
instruction events. It seems old versions of libipt, the actual decoding
library, didn't require these, but modern version require it (you can
read more here
https://github.com/intel/libipt/blob/master/doc/howto_libipt.md). These
events signal overflows of the internal PT buffer in the CPU,
enable/disable events of tracing, async cpu events, interrupts, etc.
I ended up refactoring a little bit the code to reduce code duplication.
In another diff I'll implement some basic tests.
This is a simple execution of the library:
(lldb) target create "/data/users/wallace/rr-project/a.out"
Current executable set to '/data/users/wallace/rr-project/a.out' (x86_64).
(lldb) plugin load liblldbIntelFeatures.so
(lldb) b main
Breakpoint 1: where = a.out`main + 8 at test.cpp:10, address = 0x00000000004007fa
(lldb) b test.cpp:14
Breakpoint 2: where = a.out`main + 50 at test.cpp:14, address = 0x0000000000400824
(lldb) r
Process 902754 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x00000000004007fa a.out`main at test.cpp:10
7 }
8
9 int main() {
-> 10 int z = 0;
11 for(int i = 0; i < 10000; i++)
12 z += fun(z);
13
Process 902754 launched: '/data/users/wallace/rr-project/a.out' (x86_64)
(lldb) processor-trace start all
(lldb) c
Process 902754 resuming
Process 902754 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 2.1
frame #0: 0x0000000000400824 a.out`main at test.cpp:14
11 for(int i = 0; i < 10000; i++)
12 z += fun(z);
13
-> 14 cout << z<< endl;
15 return 0;
16 }
(lldb) processor-trace show-instr-log
thread #1: tid=902754
0x7ffff72299b9 <+9>: addq $0x8, %rsp
0x7ffff72299bd <+13>: retq
0x4007ed <+16>: addl $0x1, %eax
0x4007f0 <+19>: leave
0x4007f1 <+20>: retq
0x400814 <+34>: addl %eax, -0x4(%rbp)
0x400817 <+37>: addl $0x1, -0x8(%rbp)
0x40081b <+41>: cmpl $0x270f, -0x8(%rbp) ; imm = 0x270F
0x400822 <+48>: jle 0x40080a ; <+24> at test.cpp:12
0x400822 <+48>: jle 0x40080a ; <+24> at test.cpp:12
```
Subscribers: mgorny, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D76872
SBPlatform::GetHostPlatform was missing the reproducer instrumentation
macros. Fixed by running lldb-instr on SBPlatform.cpp:
$ ./bin/lldb-instr ../llvm-project/lldb/source/API/SBPlatform.cpp
This patch fixes a crash that happens on the DWARF expression evaluator
when trying to access the top of the stack while it's empty.
rdar://60512489
Differential Revision: https://reviews.llvm.org/D77108
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
This patch fixes a crash that happens on the DWARF expression evaluator
when trying to access the top of the stack while it's empty.
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
Leverage ARM ELF build attribute section to create ELF attribute section
for RISC-V. Extract the common part of parsing logic for this section
into ELFAttributeParser.[cpp|h] and ELFAttributes.[cpp|h].
Differential Revision: https://reviews.llvm.org/D74023
The FileCollector in LLDB collects every files that's used during a
debug session when capture is enabled. This ensures that the reproducer
only contains the files necessary to reproduce. This approach is not a
good fit for the dSYM bundle, which is a directory on disk, but should
be treated as a single unit.
On macOS LLDB have automatically find the matching dSYM for a binary by
its UUID. Having a incomplete dSYM in a reproducer can break debugging
even when reproducers are disabled.
This patch adds a was to specify a directory of interest to the
reproducers. It is called from SymbolVendorMacOSX with the path of the
dSYMs used by LLDB.
Differential revision: https://reviews.llvm.org/D76672