We noticed that `apropos backtrace` did not return the `bt` alias. This change adds the
word "backtrace" to the help for `bt`. It also updates `thread backtrace` to keep the
language used roughly in sync.
# Motivation
Currently, the user can already get the "transcript" (for "what is the
transcript", see `CommandInterpreter::SaveTranscript`). However, the
only way to obtain the transcript data as a user is to first destroy the
debugger, then read the save directory. Note that destroy-callbacks
cannot be used, because 1\ transcript data is private to the command
interpreter (see `CommandInterpreter.h`), and 2\ the writing of the
transcript is *after* the invocation of destory-callbacks (see
`Debugger::Destroy`).
So basically, there is no way to obtain the transcript:
* during the lifetime of a debugger (including the destroy-callbacks,
which often performs logging tasks, where the transcript can be useful)
* without relying on external storage
In theory, there are other ways for user to obtain transcript data
during a debugger's life cycle:
* Use Python API and intercept commands and results.
* Use CLI and record console input/output.
However, such ways rely on the client's setup and are not supported
natively by LLDB.
# Proposal
Add a new Python API `SBCommandInterpreter::GetTranscript()`.
Goals:
* It can be called at any time during the debugger's life cycle,
including in destroy-callbacks.
* It returns data in-memory.
Structured data:
* To make data processing easier, the return type is `SBStructuredData`.
See comments in code for how the data is organized.
* In the future, `SaveTranscript` can be updated to write different
formats using such data (e.g. JSON). This is probably accompanied by a
new setting (e.g. `interpreter.save-session-format`).
# Alternatives
The return type can also be `std::vector<std::pair<std::string,
SBCommandReturnObject>>`. This will make implementation easier, without
having to translate it to `SBStructuredData`. On the other hand,
`SBStructuredData` can convert to JSON easily, so it's more convenient
for user to process.
# Privacy
Both user commands and output/error in the transcript can contain
privacy data. However, as mentioned, the transcript is already available
to the user. The addition of the new API doesn't increase the level of
risk. In fact, it _lowers_ the risk of privacy data being leaked later
on, by avoiding writing such data to external storage.
Once the user (or their code) gets the transcript, it will be their
responsibility to make sure that any required privacy policies are
guaranteed.
# Tests
```
bin/llvm-lit -sv ../external/llvm-project/lldb/test/API/python_api/interpreter/TestCommandInterpreterAPI.py
```
```
bin/llvm-lit -sv ../external/llvm-project/lldb/test/API/commands/session/save/TestSessionSave.py
```
---------
Co-authored-by: Roy Shi <royshi@meta.com>
Co-authored-by: Med Ismail Bennani <ismail@bennani.ma>
These are hardcoded strings that are already present in the data section
of the binary, no need to immediately place them in the ConstString
StringPools. Lots of code still calls `GetBroadcasterClass` and places
the return value into a ConstString. Changing that would be a good
follow-up.
Additionally, calls to these functions are still wrapped in ConstStrings
at the SBAPI layer. This is because we must guarantee the lifetime of
all strings handed out publicly.
Adding command interpreter statistics into "statistics dump" command so
that we can track the command usage frequency for telemetry purpose.
This is useful to answer questions like what is the most frequently used
lldb commands across all our users.
---------
Co-authored-by: jeffreytan81 <jeffreytan@fb.com>
If adding a user commands fails because a command with the same name
already exists, we only say that "force replace is not set" without
telling the user _how_ to set it. There are two ways to do so; this
commit changes the error message to mention both.
The problem is that the when the "attach" command is initiated, the
ExecutionContext for the command has a process - it's the exited one
from the previour run. But the `attach wait` creates a new process for
the attach, and then errors out instead of interrupting when it finds
that its process and the one in the command's ExecutionContext don't
match.
This change checks that if we're returning a target from
GetExecutionContext, we fill the context with it's current process, not
some historical one.
Previously we would check all built-ins first for suggestions,
then check built-ins and aliases. This meant that if you had
an alias brkpt -> breakpoint, "br" would complete to "breakpoint".
Instead of giving you the choice of "brkpt" or "breakpoint".
ConstString can be implicitly converted into a llvm::StringRef. This is
very useful in many places, but it also hides places where we are
creating a ConstString only to use it as a StringRef for the entire
lifespan of the ConstString object.
I locally removed the implicit conversion and found some of the places we
were doing this.
Differential Revision: https://reviews.llvm.org/D159237
StreamFile subclasses Stream (from lldbUtility) and is backed by a File
(from lldbHost). It does not depend on anything from lldbCore or any of its
sibling libraries, so I think it makes sense for this to live in
lldbHost instead.
Differential Revision: https://reviews.llvm.org/D157460
Also, make it possible for new Targets which haven't been added to
the TargetList yet to check for interruption, and add a few more
places in building modules where we can check for interruption.
Differential Revision: https://reviews.llvm.org/D154542
This patch should allow the user to set specific auto-completion type
for their custom commands.
To do so, we had to hoist the `CompletionType` enum so the user can
access it and add a new completion type flag to the CommandScriptAdd
Command Object.
So now, the user can specify which completion type will be used with
their custom command, when they register it.
This also makes the `crashlog` custom commands use disk-file completion
type, to browse through the user file system and load the report.
Differential Revision: https://reviews.llvm.org/D152011
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
Use templates to simplify {Get,Set}PropertyAtIndex. It has always
bothered me how cumbersome those calls are when adding new properties.
After this patch, SetPropertyAtIndex infers the type from its arguments
and GetPropertyAtIndex required a single template argument for the
return value. As an added benefit, this enables us to remove a bunch of
wrappers from UserSettingsController and OptionValueProperties.
Differential revision: https://reviews.llvm.org/D149774
The majority of call sites are nullptr as the execution context.
Refactor OptionValueProperties to make the argument optional and
simplify all the callers.
Similar to fdbe7c7faa54, refactor OptionValueProperties to return a
std::optional instead of taking a fail value. This allows the caller to
handle situations where there's no value, instead of being unable to
distinguish between the absence of a value and the value happening the
match the fail value. When a fail value is required,
std::optional::value_or() provides the same functionality.
Add a new setting (debugger.external-editor) to specify an external
editor. The setting takes precedence over the existing
LLDB_EXTERNAL_EDITOR environment variable.
Differential revision: https://reviews.llvm.org/D149565
This patch refactors the macOS implementation of
OpenFileInExternalEditor. It fixes an AppleEvent memory leak, the
caching of LLDB_EXTERNAL_EDITOR and speculatively fixes a crash when
CFURL is NULL (rdar://108633464). The new code also improves error
handling, readability and documents calls to the CoreFoundation Launch
Services APIs.
A bunch of the Launch Services APIs have been deprecated
(LSFindApplicationForInfo, LSOpenURLsWithRole). The preferred API is
LSOpenCFURLRef but it doesn't specifying the "location" Apple Event
which is used to highlight the current line and switching over would
regress the existing behavior.
rdar://108633464
Differential revision: https://reviews.llvm.org/D149482
Some LLDB set ups need to hide certain commands for security reasons, so I'm adding a flag that allows removing non-user commands.
Differential Revision: https://reviews.llvm.org/D149312
Fix logic for repeat commands, so that regex commands (specificially `bt`) are
given the opportunity to provide a repeat command.
rdar://104562616
Differential Revision: https://reviews.llvm.org/D143695
Redefine the `p` alias to the `dwim-print` command instead of `expression`.
See https://reviews.llvm.org/D138315 for the introduction of `dwim-print`.
To summarize, `dwim-print` is, as the name suggests, a command for printing. How a value
gets printed, is decided by `dwim-print`. In some cases, `dwim-print` will print values
using the same means as `frame variable` (because it's generally more reliable and
faster that `expression` evaluation), and in other cases `dwim-print` uses the same code
path as `expression`.
This change has been tested in two different ways:
1. Re-aliasing `p` to `dwim-print`, as in this patch
2. Redefinining the `expression` command to `CommandObjectDWIMPrint`
Previously, many of the lldb's tests used `p`, and which meant a test run with `p`
aliases to `dwim-print` was a good way to test `dwim-print`. However most of those tests
were updated to use `expression` explicitly (in anticipation of this change). Now, the
best way to test `dwim-print` is the second approach:
```
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index 373c894f34f5..9c943cd30c7c 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -539,7 +539,7 @@ void CommandInterpreter::LoadCommandDictionary() {
REGISTER_COMMAND_OBJECT("diagnostics", CommandObjectDiagnostics);
REGISTER_COMMAND_OBJECT("disassemble", CommandObjectDisassemble);
REGISTER_COMMAND_OBJECT("dwim-print", CommandObjectDWIMPrint);
- REGISTER_COMMAND_OBJECT("expression", CommandObjectExpression);
+ REGISTER_COMMAND_OBJECT("expression", CommandObjectDWIMPrint);
REGISTER_COMMAND_OBJECT("frame", CommandObjectMultiwordFrame);
REGISTER_COMMAND_OBJECT("gui", CommandObjectGUI);
REGISTER_COMMAND_OBJECT("help", CommandObjectHelp);
```
When the test suite is run with this change, there are two main categories of test
failures for specific to features that `dwim-print` intentionally doesn't support:
1. Top level expressions (`--top-level`/`-p`)
2. Multiline expressions
In cases where the behavior of `expression` is needed, users can use `expression` at
those times.
Differential Revision: https://reviews.llvm.org/D145189
Redefine the `p` alias to the `dwim-print` command instead of `expression`.
See https://reviews.llvm.org/D138315 for the introduction of `dwim-print`.
To summarize, `dwim-print` is, as the name suggests, a command for printing. How a value
gets printed, is decided by `dwim-print`. In some cases, `dwim-print` will print values
using the same means as `frame variable` (because it's generally more reliable and
faster that `expression` evaluation), and in other cases `dwim-print` uses the same code
path as `expression`.
This change has been tested in two different ways:
1. Re-aliasing `p` to `dwim-print`, as in this patch
2. Redefinining the `expression` command to `CommandObjectDWIMPrint`
Previously, many of the lldb's tests used `p`, and which meant a test run with `p`
aliases to `dwim-print` was a good way to test `dwim-print`. However most of those tests
were updated to use `expression` explicitly (in anticipation of this change). Now, the
best way to test `dwim-print` is the second approach:
```
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index 373c894f34f5..9c943cd30c7c 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -539,7 +539,7 @@ void CommandInterpreter::LoadCommandDictionary() {
REGISTER_COMMAND_OBJECT("diagnostics", CommandObjectDiagnostics);
REGISTER_COMMAND_OBJECT("disassemble", CommandObjectDisassemble);
REGISTER_COMMAND_OBJECT("dwim-print", CommandObjectDWIMPrint);
- REGISTER_COMMAND_OBJECT("expression", CommandObjectExpression);
+ REGISTER_COMMAND_OBJECT("expression", CommandObjectDWIMPrint);
REGISTER_COMMAND_OBJECT("frame", CommandObjectMultiwordFrame);
REGISTER_COMMAND_OBJECT("gui", CommandObjectGUI);
REGISTER_COMMAND_OBJECT("help", CommandObjectHelp);
```
When the test suite is run with this change, there are two main categories of test
failures for specific to features that `dwim-print` intentionally doesn't support:
1. Top level expressions (`--top-level`/`-p`)
2. Multiline expressions
In cases where the behavior of `expression` is needed, users can use `expression` at
those times.
Differential Revision: https://reviews.llvm.org/D145189
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated. The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.
This is part of an effort to migrate from llvm::Optional to
std::optional:
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
Implements `dwim-print`, a printing command that chooses the most direct,
efficient, and resilient means of printing a given expression.
DWIM is an acronym for Do What I Mean. From Wikipedia, DWIM is described as:
> attempt to anticipate what users intend to do, correcting trivial errors
> automatically rather than blindly executing users' explicit but
> potentially incorrect input
The `dwim-print` command serves as a single print command for users who don't
yet know, or prefer not to know, the various lldb commands that can be used to
print, and when to use them.
This initial implementation is the base foundation for `dwim-print`. It accepts
no flags, only an expression. If the expression is the name of a variable in
the frame, then effectively `frame variable` is used to get, and print, its
value. Otherwise, printing falls back to using `expression` evaluation. In this
initial version, frame variable paths will be handled with `expression`.
Following this, there are a number of improvements that can be made. Some
improvements include supporting `frame variable` expressions or registers.
To provide transparency, especially as the `dwim-print` command evolves, a new
setting is also introduced: `dwim-print-verbosity`. This setting instructs
`dwim-print` to optionally print a message showing the effective command being
run. For example `dwim-print var.meth()` can print a message such as: "note:
ran `expression var.meth()`".
See https://discourse.llvm.org/t/dwim-print-command/66078 for the proposal and
discussion.
Differential Revision: https://reviews.llvm.org/D138315
This patch will automatically open LLDB's saved transcript file on the
graphical editor if lldb is running under an interactive graphical session.
This can be controlled by a new setting: `interpreter.open-transcript-in-editor`
rdar://92692106
Differential Revision: https://reviews.llvm.org/D137137
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
Add a "diagnostics dump" command to, as the name implies, dump the
diagnostics to disk. The goal of this command is to let the user
generate the diagnostics in case of an issue that doesn't cause the
debugger to crash.
This command is also critical for testing, where we don't want to cause
a crash to emit the diagnostics.
Differential revision: https://reviews.llvm.org/D135622
If a process has multiple threads, the thread with the stop
info might not be the first one in the thread list.
On Windows, under certain circumstances, processes seem to have
one or more extra threads that haven't been launched by the
executable itself, waiting in NtWaitForWorkViaWorkerFactory. If the
main (stopped) thread isn't the first one in the list (the order
seems nondeterministic), DidProcessStopAbnormally() would return
false prematurely, instead of inspecting later threads.
The main observable effect of DidProcessStopAbnormally() erroneously
returning false, is when running lldb with multiple "-o" parameters
to specify multiple commands to execute on the command line.
After an abnormal stop, lldb would stop executing "-o" parameters
and execute "-k" parameters instead - but due to this issue, it
would instead keep executing "-o" parameters as if there was no
abnormal stop. (If multiple parameters are specified via a script
file via the "-s" option, all of the commands in that file are
executed regardless of whether there's an abnormal stop inbetween.)
Differential Revision: https://reviews.llvm.org/D134037
This reverts commit ac05bc0524c66c74278b26742896a4c634c034cf.
I had incorrectly removed one set of checks in the option handling in
Options::ParseAlias because I couldn't see what it is for. It was a
bit obscure, but it handled the case where you pass "-something=other --"
as the input_line, which caused the built-in "run" alias not to return
the right value for IsDashDashCommand, causing TestHelp.py to fail.
This reverts commit 6c089b2af5d8d98f66b27b67f70958f520820a76.
This was causing the test test_help_run_hides_options from TestHelp.py to
fail on Linux and Windows (but the test succeeds on macOS). The decision
to print option information is determined by CommandObjectAlias::IsDashDashCommand
which was changed, but only by replacing an inline string constant with a const char *
CommandInterpreter::g_argument which has the same string value. I can't see why this
would fail, I'll have to spin up a vm to see if I can repo there.
This is particularly a problem for alias construction, where you might
want to have a backtick surrounded option in the alias. Before this
patch:
command alias expression -Z \`argc\` -- argv
for instance would be rendered as:
expression -Z argc -- argv
and would fail to work.
Differential Revision: https://reviews.llvm.org/D133045
LLVM contains a helpful function for getting the size of a C-style
array: `llvm::array_lengthof`. This is useful prior to C++17, but not as
helpful for C++17 or later: `std::size` already has support for C-style
arrays.
Change call sites to use `std::size` instead.
Differential Revision: https://reviews.llvm.org/D133501
When the string passed to PrintCommandOutput doesn't end with a newline,
`written` will exceed `size` and result in an lldbassert.
After 8e776bb660dda6c51ce7ca6cea641db1f47aa9cf we don't really need
written anymore and we can check whether `str` is empty instead. This
patch simplifies the code and removes the assert that's no longer
relevant.
Differential revision: https://reviews.llvm.org/D126081
This adds a setting (`target.max-children-depth`) that will provide a default value for the `--depth` flag used by `expression` and `frame variable`.
The new setting uses the same default that's currently fixed in source: `UINT32_MAX`.
This provides two purposes:
1. Allowing downstream forks to provide a customized default.
2. Allowing users to set their own default.
Following `target.max-children-count`, a warning is emitted when the max depth is reached. The warning lets users know which flags or settings they can customize. This warning is shown only when the limit is the default value.
rdar://87466495
Differential Revision: https://reviews.llvm.org/D123954
The driver can push a null ExecutionContext on to this stack,
and later calls to SBCommandInterpreter::HandleCommand which
don't specify an ExecutionContext can pull an entry from the
stack, resulting in settings that aren't applied.
Differential Revision: https://reviews.llvm.org/D111209
rdar://81489207
Protecting against accidental overwriting of commands is good, but
having to pass a flag to overwrite the command when developing your
commands is pretty annoying. This adds a setting to defeat the protection
so you can do this once at the start of your session and not have to
worry about it again.
Differential Revision: https://reviews.llvm.org/D122680