This commit cleans up the includes in the `lldb-dap` subfolder. The main
motivation was that I got annoyed by `clangd` always complaining about
unused includes while working on lldb-dap.
This commit improves the auto-completion in the Debug Console provided
by VS-Code.
So far, we were always suggesting completions for both LLDB commands and
for variables / expressions, even if the heuristic already determined
how the given string will be executed, e.g., because the user explicitly
typed the escape prefix. Furthermore, auto-completion after the escape
character was broken, since the offsets were not adjusted correctly.
With this commit we now correctly take this into account.
Even with this commit, auto-completion does not always work reliably:
* VS Code only requests auto-completion after typing the first
alphabetic character, but not after punctuation characters. This means
that no completions are provided after typing "`"
* LLDB does not provide autocompletions if a string is an exact match.
This means if a user types `l` (which is a valid command), LLDB will not
provide "language" and "log" as potential completions. Even worse, VS
Code caches the completion and does client-side filtering. Hence, even
after typing `la`, no auto-completion for "language" is shown in the UI.
Those issues might be fixed in follow-up commits. Also with those known
issues, the experience is already much better with this commit.
Furthermore, I updated the README since I noticed that it was slightly
inaccurate.
The `enable` prefix is a filler word which adds no additional
information. Rename the setting to `displayExtendedBacktrace`
Given that this setting was only introduced a month ago, and that there
has not been any release since then, I assume that usage is still rather
low. As such, it should be fine to not provide backwards-compatibility
workarounds.
This commit implements support for the "declaration location" recently
added by microsoft/debug-adapter-protocol#494 to the debug adapter
protocol.
For the `declarationLocationReference` we need a variable ID similar to
the `variablesReference`. I decided to simply reuse the
`variablesReference` here and renamed `Variables::expandable_variables`
and friends accordingly. Given that almost all variables have a
declaration location, we now assign those variable ids to all variables.
While `declarationLocationReference` effectively supersedes
`$__lldb_extensions.declaration`, I did not remove this extension, yet,
since I assume that there are some closed-source extensions which rely
on it.
I tested this against VS-Code Insiders. However, VS-Code Insiders
currently only supports `valueLoctionReference` and not
`declarationLocationReference`, yet. Locally, I hence published the
declaration locations as value locations, and VS Code Insiders navigated
to the expected places. Looking forward to proper VS Code support for
`declarationLocationReference`.
As specified in the docs,
1) raw_string_ostream is always unbuffered and
2) the underlying buffer may be used directly
( 65b13610a5226b84889b923bae884ba395ad084d for further reference )
* Don't call raw_string_ostream::flush(), which is essentially a no-op.
* Avoid unneeded calls to raw_string_ostream::str(), to avoid excess
indirection.
Added support for "supportsInstructionBreakpoints" capability and now it
this command is triggered when we set instruction breakpoint.
We need this support as part of enabling disassembly view debugging.
Following features should work as part of this feature enablement:
1. Settings breakpoints in disassembly view: Unsetting the breakpoint is
not happening from the disassembly view. Currently we need to unset
breakpoint manually from the breakpoint List. Multiple breakpoints are
getting set for the same $
2. Step over, step into, continue in the disassembly view
The format for DisassembleRequest and DisassembleResponse at
https://raw.githubusercontent.com/microsoft/vscode/master/src/vs/workbench/contrib/debug/common/debugProtocol.d.ts
.
Ref Images:
Set instruction breakpoint in disassembly view:

After issuing continue:

---------
Co-authored-by: Santhosh Kumar Ellendula <sellendu@hu-sellendu-hyd.qualcomm.com>
Co-authored-by: Santhosh Kumar Ellendula <sellendu@hu-sellendu-lv.qualcomm.com>
We have got several customer reporting of slow stepping over the past
year in VSCode.
Profiling shows the slow stepping is caused by `stackTrace` request
which can take around 1 second for certain targets. Since VSCode sends
`stackTrace` during each stop event, the slow `stackTrace` request would
slow down stepping in VSCode. Below is the hot path:
```
|--68.75%--lldb_dap::DAP::HandleObject(llvm::json::Object const&)
| |
| |--57.70%--(anonymous namespace)::request_stackTrace(llvm::json::Object const&)
| | |
| | |--54.43%--lldb::SBThread::GetCurrentExceptionBacktrace()
| | | lldb_private::Thread::GetCurrentExceptionBacktrace()
| | | lldb_private::Thread::GetCurrentException()
| | | lldb_private::ItaniumABILanguageRuntime::GetExceptionObjectForThread(std::shared_ptr<lldb_private::Thread>)
| | | |
| | | |--53.43%--lldb_private::FunctionCaller::ExecuteFunction(lldb_private::ExecutionContext&, unsigned long*, lldb_private::EvaluateExpressionOptions const&, lldb_private::DiagnosticManager&, lldb_private::Value&)
| | | | |
| | | | |--25.23%--lldb_private::FunctionCaller::InsertFunction(lldb_private::ExecutionContext&, unsigned long&, lldb_private::DiagnosticManager&)
| | | | | |
| | | | | |--24.56%--lldb_private::FunctionCaller::WriteFunctionWrapper(lldb_private::ExecutionContext&, lldb_private::DiagnosticManager&)
| | | | | | |
| | | | | | |--19.73%--lldb_private::ExpressionParser::PrepareForExecution(unsigned long&, unsigned long&, std::shared_ptr<lldb_private::IRExecutionUnit>&, lldb_private::ExecutionContext&, bool&, lldb_private::ExecutionPolicy)
| | | | | | | lldb_private::ClangExpressionParser::DoPrepareForExecution(unsigned long&, unsigned long&, std::shared_ptr<lldb_private::IRExecutionUnit>&, lldb_private::ExecutionContext&, bool&, lldb_private::ExecutionPolicy)
| | | | | | | lldb_private::IRExecutionUnit::GetRunnableInfo(lldb_private::Status&, unsigned long&, unsigned long&)
| | | | | | | |
```
The hot path is added by https://reviews.llvm.org/D156465 which should
at least be disabled for Linux. Note: I am seeing similar performance
hot path on Mac.
This PR hides the feature behind `enableDisplayExtendedBacktrace` option
which needs to be enabled on-demand.
---------
Co-authored-by: jeffreytan81 <jeffreytan@fb.com>
Previously, when output like `"hello\nworld\n"` was produced by lldb (or
the process) the message would be sent as a single Output event. By
being a single event this causes VS Code to treat this as a single
message in the console when handling displaying and filtering in the
Debug Console.
Instead, with these changes we send each line as its own event. This
results in VS Code representing each line of output from lldb-dap as an
individual output message.
Resolves#105444
…lly registered languages
First of all, this is done to support exceptions for the Mojo language,
but it's done in a way that will benefit any other plugin language.
1. I added a new lldb-dap CLI argument (not DAP field) called
`pre-init-commands`. These commands are executed before DAP
initialization. The other `init-commands` are executed after DAP
initialization. It's worth mentioning that the debug adapter returns to
VSCode the list of supported exception breakpoints during DAP
initialization, which means that I need to register the Mojo plugin
before that initialization step, hence the need for `pre-init-commands`.
In general, language plugins should be registered in that step, as they
affect the capabilities of the debugger.
2. I added a set of APIs for lldb-dap to query information of each
language related to exception breakpoints. E.g. whether a language
supports throw or catch breakpoints, how the throw keyword is called in
each particular language, etc.
3. I'm realizing that the Swift support for exception breakpoints in
lldb-dap should have been implemented in this way, instead of hardcoding
it.
New fixes:
- properly init the `std::optional<std::vector>` to an empty vector as
opposed to `{}` (which was effectively `std::nullopt`).
---------
Co-authored-by: Vy Nguyen <oontvoo@users.noreply.github.com>
Re-apply https://github.com/llvm/llvm-project/pull/87550 with fixes.
Details:
Some tests in fuchsia failed because of the newly added assertion.
This was because `GetExceptionBreakpoint()` could be called before
`g_dap.debugger` was initted.
The fix here is to just lazily populate the list in
GetExceptionBreakpoint() rather than assuming it's already been initted.
(There is some nuisance here because we can't simply just populate it in
DAP::DAP(), which is a global ctor and is called before
`SBDebugger::Initialize()` is called. )
ResolveCommand will not succeed for an alias command with arguments, and
the code wasn't providing any. Replace that with explicit query(ies) for
the existence of a command with the given name.
lldb-dap was setting a flag which was meant to shut it down as soon as
it sent a terminated event. The problem with this flag is two-fold:
- as far as I can tell (definitely not an expert here), there's no
justification for this in the protocol spec. The only way I found to
shut the server down was to send it a disconnect request.
- the flag did not actually work most of the time, because it's only
checked between requests so nothing will happen if the server starts
listening for a new request before a different thread manages to send
the terminated event. And since the next request is usually the
disconnect request, everything will operate normally.
The combination of these two things meant that the issue was largely
unnoticable, except for rare flaky test failures, which happened when
the handler thread was too slow, and checked the flag after it has
already been said. This caused the test suite to complain as it did not
get a response to the disconnect request. This situation could be
s(t)imulated by adding a sleep to the and of the main loop, which
delayed the flag check, and caused the DAP tests to fail reliably.
This patch changes the shutdown condition to only trigger when the
disconnect request has been received. Since the flag can now only be set
from the handler thread, it no longer needs to be atomic.
The previous logic for determining if an expression was a command or
variable expression in the repl would incorrectly identify the context
in many common cases where a local variable name partially overlaps with
the repl input.
For example:
```
int foo() {
int var = 1; // break point, evaluating "p var", previously emitted a warning
}
```
Instead of checking potentially multiple conflicting values against the
expression input, I updated the heuristic to only consider the first
term. This is much more reliable at eliminating false positives when the
input does not actually hide a local variable.
Additionally, I updated the warning on conflicts to occur anytime the
conflict is detected since the specific conflict can change based on the
current input. This also includes additional details on how users can
change the behavior.
Example Debug Console output from
lldb/test/API/tools/lldb-dap/evaluate/main.cpp:11 breakpoint 3.
```
lldb-dap> var + 3
Warning: Expression 'var' is both an LLDB command and variable. It will be evaluated as a variable. To evaluate the expression as an LLDB command, use '`' as a prefix.
45
lldb-dap> var + 1
Warning: Expression 'var' is both an LLDB command and variable. It will be evaluated as a variable. To evaluate the expression as an LLDB command, use '`' as a prefix.
43
```
This adds support for optionally prefixing any command with `?` and/or
`!`.
- `?` prevents the output of a commands to be printed to the console
unless it fails.
- `!` aborts the dap if the command fails.
They come in handy when programmatically running commands on behalf of
the user without wanting them to know unless they fail, or when a
critical setup is required as part of launchCommands and it's better to
abort on failures than to silently skip.
When this option gets enabled, descriptions of threads will be generated
using the format provided in the launch configuration instead of
generating it manually in the dap code. This allows lldb-dap to show an
output similar to the one in the CLI.
This is very similar to https://github.com/llvm/llvm-project/pull/71843
When this option gets enabled, descriptions of stack frames will be
generated using the format provided in the launch configuration instead
of simply calling `SBFrame::GetDisplayFunctionName`. This allows
lldb-dap to show an output similar to the one in the CLI.
We've been using the backtick as our escape character, however that
leads to a weird experience on VS Code, because on most hosts, as soon
as you type the backtick on VS Code, the IDE will introduce another
backtick. As changing the default escape character might be out of
question because other plugins might rely on it, we can instead
introduce an option to change this variable upon lldb-vscode
initialization.
FWIW, my users will be using : instead ot the backtick.
Rename lldb-vscode to lldb-dap. This change is largely mechanical. The
following substitutions cover the majority of the changes in this
commit:
s/VSCODE/DAP/
s/VSCode/DAP/
s/vscode/dap/
s/g_vsc/g_dap/
Discourse RFC:
https://discourse.llvm.org/t/rfc-rename-lldb-vscode-to-lldb-dap/74075/