So far, the syntax was `target frame-provider register <cmd-options>
[<run-args>]`. Note the optional `run-args` at the end. They are
completely ignored by the actual command, but the command line parser
still accepts them.
This commit removes them.
This was probably a copy-paste error from `CommandObjectProcessLaunch`
which was probably used as a blue-print for `target frame-provider
register`.
CommandObjectBreakpointAddPattern is a raw command. I was adjusting the
patch for changes to handle the dummy target changes done while the
patch was in review, and I copied the lines to the beginning of the
DoExecute, but in the case of raw commands, you have to do the option
parsing by hand, and this was before the parsing was done so the state
wasn't determined yet.
Someone came up with a clever idea for a new breakpoint type, but we
couldn't figure out how to add it in an ergonomic way because
`breakpoint set` has used up all the short-option characters. And even
if they did find a way to add it, the help for `break set` is so
confusing - because of the way it is implemented - that very few people
would detect the addition.
The basic problem is that `break set` distinguishes amongst the
fundamental breakpoint types it offers by which "required option" you
provide. If you pass a `-a` you are setting an address breakpoint, if
`-n`, `-F`, etc. a symbol name based breakpoint. And so forth. That is
however pretty hard to discern from the option grouping printing from
`help break set`. `break set` also suffers from the problem that it uses
common options in different ways depending on which "required" option is
present, which makes documenting the various behaviors difficult. And as
we run out of single letters it makes extending it difficult to
impossible.
This PR fixes that situation by adding a new command for adding
breakpoints - `break add`. The new command specifies the "breakpoint
types" as subcommands of `break add` rather than distinguishing them by
their being one of the "required" options the way `break set` does. That
both makes it much clearer what the breakpoint types actually are, and
means that the option set can be dedicated to that particular breakpoint
type, and so the help for each is less cluttered, and can be documented
properly for each usage.
Instead of trying to parse the meaning of:
```
(lldb) help break set
Sets a breakpoint or set of breakpoints in the executable.
Syntax: breakpoint set <cmd-options>
Command Options Usage:
breakpoint set [-DHd] -l <linenum> [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-R <address>] [-N <breakpoint-name>] [-u <column>] [-f <filename>] [-m <boolean>] [-s <shlib-name>] [-K <boolean>]
breakpoint set [-DHd] -a <address-expression> [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-N <breakpoint-name>] [-s <shlib-name>]
breakpoint set [-DHd] -n <function-name> [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-R <address>] [-N <breakpoint-name>] [-f <filename>] [-L <source-language>] [-s <shlib-name>] [-K <boolean>]
breakpoint set [-DHd] -F <fullname> [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-R <address>] [-N <breakpoint-name>] [-f <filename>] [-L <source-language>] [-s <shlib-name>] [-K <boolean>]
breakpoint set [-DHd] -S <selector> [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-R <address>] [-N <breakpoint-name>] [-f <filename>] [-L <source-language>] [-s <shlib-name>] [-K <boolean>]
breakpoint set [-DHd] -M <method> [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-R <address>] [-N <breakpoint-name>] [-f <filename>] [-L <source-language>] [-s <shlib-name>] [-K <boolean>]
breakpoint set [-DHd] -r <regular-expression> [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-R <address>] [-N <breakpoint-name>] [-f <filename>] [-L <source-language>] [-s <shlib-name>] [-K <boolean>]
breakpoint set [-DHd] -b <function-name> [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-R <address>] [-N <breakpoint-name>] [-f <filename>] [-L <source-language>] [-s <shlib-name>] [-K <boolean>]
breakpoint set [-ADHd] -p <regular-expression> [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-N <breakpoint-name>] [-f <filename>] [-m <boolean>] [-s <shlib-name>] [-X <function-name>]
breakpoint set [-DHd] -E <source-language> [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-N <breakpoint-name>] [-h <boolean>] [-w <boolean>]
breakpoint set [-DHd] -P <python-class> [-k <none>] [-v <none>] [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-N <breakpoint-name>] [-f <filename>] [-s <shlib-name>]
breakpoint set [-DHd] -y <linespec> [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-R <address>] [-N <breakpoint-name>] [-m <boolean>] [-s <shlib-name>] [-K <boolean>]
```
We instead offer:
```
(lldb) help break add
Commands to add breakpoints of various types
Syntax: breakpoint add
Access the breakpoint search kernels built into lldb. Along with specifying the
search kernel, each breakpoint add operation can specify a common set of
"reaction" options for each breakpoint. The reaction options can also be
modified after breakpoint creation using the "breakpoint modify" command.
The following subcommands are supported:
address -- Add breakpoints by raw address
exception -- Add breakpoints on language exceptions. If no language is specified, break on exceptions for all supported languages
file -- Add breakpoints on lines in specified source files
name -- Add breakpoints matching function or symbol names
pattern -- Add breakpoints matching patterns in the source text Expects 'raw' input (see 'help raw-input'.)
scripted -- Add breakpoints using a scripted breakpoint resolver.
For more help on any particular subcommand, type 'help <command> <subcommand>'.
```
The individual subcommand helps are also easier to read. They are still
a little too verbose because they all repeat the options for the
`reactions`. A general fix for our help system would be when a command
incorporates an OptionGroup whole into the command options, help would
show the option group name - which you could separately look up. But
even without that:
```
(lldb) help br a a
Add breakpoints by raw address
Syntax: breakpoint add address <cmd-options> <address> [<address> [...]]
Command Options Usage:
breakpoint add address [-DHde] [-G <boolean>] [-C <command>] [-c <expr>] [-Y <source-language>] [-i <count>] [-o <boolean>] [-q <queue-name>] [-t <thread-id>] [-x <thread-index>] [-T <thread-name>] [-N <breakpoint-name>] [-s <shlib-name>] <address> [<address> [...]]
-C <command> ( --command <command> )
A command to run when the breakpoint is hit, can be provided more than once, the commands will be run in left-to-right order.
-D ( --dummy-breakpoints )
Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets.
-G <boolean> ( --auto-continue <boolean> )
The breakpoint will auto-continue after running its commands.
-H ( --hardware )
Require the breakpoint to use hardware breakpoints.
-N <breakpoint-name> ( --breakpoint-name <breakpoint-name> )
Adds this name to the list of names for this breakpoint. Can be specified more than once.
-T <thread-name> ( --thread-name <thread-name> )
The breakpoint stops only for the thread whose thread name matches this argument.
-Y <source-language> ( --condition-language <source-language> )
Specifies the Language to use when executing the breakpoint's condition expression.
-c <expr> ( --condition <expr> )
The breakpoint stops only if this condition expression evaluates to true.
-d ( --disable )
Disable the breakpoint.
-e ( --enable )
Enable the breakpoint.
-i <count> ( --ignore-count <count> )
Set the number of times this breakpoint is skipped before stopping.
-o <boolean> ( --one-shot <boolean> )
The breakpoint is deleted the first time it stop causes a stop.
-q <queue-name> ( --queue-name <queue-name> )
The breakpoint stops only for threads in the queue whose name is given by this argument.
-s <shlib-name> ( --shlib <shlib-name> )
Set the breakpoint at an address relative to sections in this shared library.
-t <thread-id> ( --thread-id <thread-id> )
The breakpoint stops only for the thread whose TID matches this argument. The token 'current' resolves to the current thread's ID.
-x <thread-index> ( --thread-index <thread-index> )
The breakpoint stops only for the thread whose index matches this argument.
This command takes options and free-form arguments. If your arguments resemble option specifiers (i.e., they start with a - or --), you must use ' --
' between the end of the command options and the beginning of the arguments.
```
is pretty readable.
This relands #165277 by reverting #169397.
This also relands the corresponding Bazel port by reverting #169410.
The original revert was due to a report of a broken build, which was
later resolved by fully clearing the build directory.
show information about the signal when the user presses `process handle
<unix-signal>` i.e
```sh
(lldb) process handle SIGWINCH
NAME PASS STOP NOTIFY DESCRIPTION
=========== ===== ===== ====== ===================
SIGWINCH true false false window size changes
```
Wanted to use the existing `GetSignalDescription` but it is expected
behaviour to return the signal name if no signal code is passed. It is
used in stop info.
65c895dfe0/lldb/source/Target/StopInfo.cpp (L1192-L1195)
This removes the dependency on clangDriver from clangFrontend and
flangFrontend.
This refactoring is part of a broader effort to support driver-managed
builds for compilations using C++ named modules and/or Clang modules.
It is required for linking the dependency scanning tooling against the
driver without introducing cyclic dependencies, which would otherwise
cause build failures when dynamic linking is enabled.
In particular, clangFrontend must no longer depend on clangDriver
for this to be possible.
This change was discussed in the following RFC:
https://discourse.llvm.org/t/rfc-new-clangoptions-library-remove-dependency-on-clangdriver-from-clangfrontend-and-flangfrontend/88773
This patch fixes and eliminates the possibility of SupportFileSP ever
being nullptr. The support file was originally treated like a value
type, but became a polymorphic type and therefore has to be stored and
passed around as a pointer.
To avoid having all the callers check the validity of the pointer, I
introduced the invariant that SupportFileSP is never null and always
default constructed. However, without enforcement at the type level,
that's fragile and indeed, we already identified two crashes where
someone accidentally broke that invariant.
This PR introduces a NonNullSharedPtr to prevent that. NonNullSharedPtr
is a smart pointer wrapper around std::shared_ptr that guarantees the
pointer is never null. If default-constructed, it creates a
default-constructed instance of the contained type. Note that I'm using
private inheritance because you shouldn't inherit from standard library
classes due to the lack of virtual destructor. So while the new
abstraction looks like a `std::shared_ptr`, it is in fact **not** a
shared pointer. Given that our destructor is trivial, we could use
public inheritance, but currently there's no need for it.
rdar://164989579
NFC patch which moves `DiagnosticsRendering` from `Utility` to `Host`.
This refactoring is needed for
https://github.com/llvm/llvm-project/pull/168603. It adds a method to
check whether the current terminal supports Unicode or not. This will be
OS dependent and a better fit for `Host`. Since `Utility` cannot depend
on `Host`, `DiagnosticsRendering` must live in `Host` instead.
This is a fixed version of #167886.
The build previously failed with `BUILD_SHARED_LIBS=ON`. After trying
that locally, I uncovered a few other instances of lldb non-plugin
libraries depending on clang transitively through lldbValueObject, so I
added the correct clang libraries to their dependencies.
Reverts llvm/llvm-project#167794
This breaks a build with BUILD_SHARED_LIBS=ON:
/usr/bin/ld: lib/liblldbCommands.a(CommandObjectTarget.cpp.o): undefined
reference to symbol '_ZN5clang22PCHContainerOperationsC1Ev
Fixing that issue leads to similar failures due to different symbols.
The ValueObject library doesn't actually depend on any plugins
currently, but it links against the C++ and ObjC language plugins. I
removed those and added NO_PLUGIN_DEPENDENCIES.
However, the build failed initally because the Commands library depends
on clangFrontend and it was previously getting it transitively through
ValueObject -> C++/ObjC Language -> clangFrontend. This makes the
dependency more explicit.
This patch extends ScriptedFrame to work with real (non-scripted)
threads,
enabling frame providers to synthesize frames for native processes.
Previously, ScriptedFrame only worked within
ScriptedProcess/ScriptedThread
contexts. This patch decouples ScriptedFrame from ScriptedThread,
allowing
users to augment or replace stack frames in real debugging sessions for
use
cases like custom calling conventions, reconstructing corrupted frames
from
core files, or adding diagnostic frames.
Key changes:
- ScriptedFrame::Create() now accepts ThreadSP instead of requiring
ScriptedThread, extracting architecture from the target triple rather
than ScriptedProcess.arch
- Added SBTarget::RegisterScriptedFrameProvider() and
ClearScriptedFrameProvider() APIs, with Target storing a
SyntheticFrameProviderDescriptor template for new threads
- Added "target frame-provider register/clear" commands for CLI access
- Thread class gains LoadScriptedFrameProvider(),
ClearScriptedFrameProvider(),
and GetFrameProvider() methods for per-thread frame provider management
- New SyntheticStackFrameList overrides FetchFramesUpTo() to lazily
provide
frames from either the frame provider or the real stack
This enables practical use of the SyntheticFrameProvider infrastructure
in
real debugging workflows.
rdar://161834688
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
We're iterating over the stop hooks so if one of them changes the stop
hook list by deleting itself or another stop hook, that invalidates our
iterator.
I chose to fix this by making a copy of the stop hook list and iterating
over that. That's a cheap operation since this is just an array of
shared pointers. But more importantly doing it this way means that if on
a stop where one stop hook deletes another, the deleted hook will always
get a chance to run. If you iterated over the list itself, then whether
that to be deleted hook gets to run would be dependent on whether it was
before or after the deleting stop hook, which would be confusing.
This avoids unintentional comparisons between `SourceLanguage` and
`LanguageType`.
Also marks `operator bool` explicit so we don't implicitly convert to
bool.
When stopped in a hidden frame (either because we selected the hidden
frame or hit a breakpoint inside it), a user most likely is intersted in
exploring the immediate frames around it. But currently issuing
`up`/`down` commands will unconditionally skip over all hidden frames.
This patch makes it so `up`/`down` commands don't skip hidden frames if
the frame we started it was a hidden frame.
Introduce the concept of internal stop hooks.
These are similar to LLDB's internal breakpoints:
LLDB itself will add them and users of LLDB will
not be able to add or remove them.
This change adds the following 3
independently-useful concepts:
* Maintain a list of internal stop hooks that will be populated by LLDB
and cannot be added to or removed from by users. They are managed in a
separate list in `Target::m_internal_stop_hooks`.
* `StopHookKind:CodeBased` and `StopHookCoded` represent a stop hook
defined by a C++ code callback (instead of command line expressions or a
Python class).
* Stop hooks that do not print any output can now also suppress the
printing of their header and description when they are hit via
`StopHook::GetSuppressOutput`.
Combining these 3 concepts we can model "internal
stop hooks" which serve the same function as
LLDB's internal breakpoints: executing built-in,
LLDB-defined behavior, leveraging the existing
mechanism of stop hooks.
This change also simplifies
`Target::RunStopHooks`. We already have to
materialize a new list for combining internal and
user stop hooks. Filter and only add active hooks to this list to avoid
the need for "isActive?"
checks later on.
For debugging and bug-finding workflows on Darwin, support
launching processes with memory tagging for binaries that are
not entitled.
This will cause the process to behave as if the binary was entitled
with:
```
<key>com.apple.security.hardened-process.checked-allocations</key>
<true/>
```
This has no effect on hardware without MTE support.
---------
Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
Currently AFAICT we don't have a way to get the MCP server socket after
it started. So this change introduces a new `protocol-server` subcommand
that allows us to query the location of a running server:
```
(lldb) protocol-server start MCP listen://localhost:0
MCP server started with connection listeners: connection://[::1]:36051, connection://[127.0.0.1]:36051
(lldb) protocol-server get MCP
MCP server connection listeners: connection://[::1]:36051, connection://[127.0.0.1]:36051
(lldb) protocol-server stop MCP
(lldb) protocol-server get MCP
error: MCP server is not running
```
This patch adds a load core time, right now we don't have much insight
into the performance of load core, especially for large coredumps. To
start collecting information on this I've added some minor
instrumentation code to measure the two call sites of `LoadCore`.
I've also added a test to validate the new metric is output in
statistics dump
This PR is a part of the effort to make the VFS used in the compiler
more explicit and consistent.
Instead of creating the VFS deep within the compiler (in
`CompilerInstance::createFileManager()`), clients are now required to
explicitly call `CompilerInstance::createVirtualFileSystem()` and
provide the base VFS from the outside.
This PR also helps in breaking up the dependency cycle where creating a
properly configured `DiagnosticsEngine` requires a properly configured
VFS, but creating properly configuring a VFS requires the
`DiagnosticsEngine`.
Both `CompilerInstance::create{FileManager,Diagnostics}()` now just use
the VFS already in `CompilerInstance` instead of taking one as a
parameter, making the VFS consistent across the instance sub-object.
This patch causes the various AST dump commands (`target modules dump
ast`/`target dump typesystem`) to be color-highlighted. I added a `bool
show_color` parameter to `SymbolFile::DumpClangAST` and
`TypeSystem::Dump`. In `TypeSystemClang` I temporarily sets the
`getShowColors` flag on the owned Clang AST (using an RAII helper) for
the duration of the AST dump. We use `Debugger::GetUseColors` to decide
whether to color the AST dump.
Some type systems require an execution context be available when working with types
(ex: Swift). This fixes `memory read --type` to support such type systems, by passing in
an execution context to `GetByteSize()`, instead of passing null.
rdar://158968545
The LLVM Style Guide says the following about error and warning messages
[1]:
> [T]o match error message styles commonly produced by other tools,
> start the first sentence with a lowercase letter, and finish the last
> sentence without a period, if it would end in one otherwise.
I often provide this feedback during code review, but we still have a
bunch of places where we have inconsistent error message, which bothers
me as a user. This PR identifies a handful of those places and updates
the messages to be consistent.
[1] https://llvm.org/docs/CodingStandards.html#error-and-warning-messages
Add a bunch of mnemonics to the command options now that they're
highlighted in the help output. This uncovered two issues:
- We had an instance where we weren't applying the ANSI formatting.
- We had a place where we were now incorrectly computing the column
width.
Both are fixed by this PR.
Format the command options tablegen file, which was created before
clang-format added support for tablegen. Small changes lead to lots of
reformatting changes which makes the diffs hard to review.
This adjusts the ProtocolServer command to default to create a new
connection listening on `localhost:0` and adds a new `ServerMetadata`
details to `~/.lldb/mcp/lldb-<pid>.json` to record information about the
current MCP server.
This can be consumed by the lldb-mcp binary to establish a connection
from an LLM client.
---------
Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
Fixes whitespace, spelling and grammatical issues in the command
options. I also formatted the affected options with clang-format and
reflowed the description where necessary.
This PR updates the tablegen emitter for command options to support a
simplified syntax to underline the mnemonic. Previously, you had to
write `${ansi.underline}<L>${ansi.normal}`, where `<L>` is the mnemonic.
This really hurt the readability of the description. With this PR, you
can write `${<L>}` instead.
**Context**
Follow-up to
[#147460](https://github.com/llvm/llvm-project/pull/147460), which added
the ability to surface register-resident variable locations.
This PR moves the annotation logic out of `Instruction::Dump()` and into
`Disassembler::PrintInstructions()`, and adds lightweight state tracking
so we only print changes at range starts and when variables go out of
scope.
---
## What this does
While iterating the instructions for a function, we maintain a “live
variable map” keyed by `lldb::user_id_t` (the `Variable`’s ID) to
remember each variable’s last emitted location string. For each
instruction:
- **New (or newly visible) variable** → print `name = <location>` once
at the start of its DWARF location range, cache it.
- **Location changed** (e.g., DWARF range switched to a different
register/const) → print the updated mapping.
- **Out of scope** (was tracked previously but not found for the current
PC) → print `name = <undef>` and drop it.
This produces **concise, stateful annotations** that highlight variable
lifetime transitions without spamming every line.
---
## Why in `PrintInstructions()`?
- Keeps `Instruction` stateless and avoids changing the
`Instruction::Dump()` virtual API.
- Makes it straightforward to diff state across instructions (`prev →
current`) inside the single driver loop.
---
## How it works (high-level)
1. For the current PC, get in-scope variables via
`StackFrame::GetInScopeVariableList(/*get_parent=*/true)`.
2. For each `Variable`, query
`DWARFExpressionList::GetExpressionEntryAtAddress(func_load_addr,
current_pc)` (added in #144238).
3. If the entry exists, call `DumpLocation(..., eDescriptionLevelBrief,
abi)` to get a short, ABI-aware location string (e.g., `DW_OP_reg3 RBX →
RBX`).
4. Compare against the last emitted location in the live map:
- If not present → emit `name = <location>` and record it.
- If different → emit updated mapping and record it.
5. After processing current in-scope variables, compute the set
difference vs. the previous map and emit `name = <undef>` for any that
disappeared.
Internally:
- We respect file↔load address translation already provided by
`DWARFExpressionList`.
- We reuse the ABI to map LLVM register numbers to arch register names.
---
## Example output (x86_64, simplified)
```
-> 0x55c6f5f6a140 <+0>: cmpl $0x2, %edi ; argc = RDI, argv = RSI
0x55c6f5f6a143 <+3>: jl 0x55c6f5f6a176 ; <+54> at d_original_example.c:6:3
0x55c6f5f6a145 <+5>: pushq %r15
0x55c6f5f6a147 <+7>: pushq %r14
0x55c6f5f6a149 <+9>: pushq %rbx
0x55c6f5f6a14a <+10>: movq %rsi, %rbx
0x55c6f5f6a14d <+13>: movl %edi, %r14d
0x55c6f5f6a150 <+16>: movl $0x1, %r15d ; argc = R14
0x55c6f5f6a156 <+22>: nopw %cs:(%rax,%rax) ; i = R15, argv = RBX
0x55c6f5f6a160 <+32>: movq (%rbx,%r15,8), %rdi
0x55c6f5f6a164 <+36>: callq 0x55c6f5f6a030 ; symbol stub for: puts
0x55c6f5f6a169 <+41>: incq %r15
0x55c6f5f6a16c <+44>: cmpq %r15, %r14
0x55c6f5f6a16f <+47>: jne 0x55c6f5f6a160 ; <+32> at d_original_example.c:5:10
0x55c6f5f6a171 <+49>: popq %rbx ; i = <undef>
0x55c6f5f6a172 <+50>: popq %r14 ; argv = RSI
0x55c6f5f6a174 <+52>: popq %r15 ; argc = RDI
0x55c6f5f6a176 <+54>: xorl %eax, %eax
0x55c6f5f6a178 <+56>: retq
```
Only transitions are shown: the start of a location, changes, and
end-of-lifetime.
---
## Scope & limitations (by design)
- Handles **simple locations** first (registers, const-in-register cases
surfaced by `DumpLocation`).
- **Memory/composite locations** are out of scope for this PR.
- Annotations appear **only at range boundaries** (start/change/end) to
minimize noise.
- Output is **target-independent**; register names come from the target
ABI.
## Implementation notes
- All annotation printing now happens in
`Disassembler::PrintInstructions()`.
- Uses `std::unordered_map<lldb::user_id_t, std::string>` as the live
map.
- No persistent state across calls; the map is rebuilt while walking
instruction by instruction.
- **No changes** to the `Instruction` interface.
---
## Requested feedback
- Placement and wording of the `<undef>` marker.
- Whether we should optionally gate this behind a setting (currently
always on when disassembling with an `ExecutionContext`).
- Preference for immediate inclusion of tests vs. follow-up patch.
---
Thanks for reviewing! Happy to adjust behavior/format based on feedback.
---------
Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
Co-authored-by: Adrian Prantl <adrian.prantl@gmail.com>
Whenever an option would use something other than the first letter of
the long option as the short option, Jim would capitalized the letter we
picked as a mnemonic. This has often been mistaken for a typo and Jim
wondered if we should stop doing this.
During the discussion, David mentioned how this reminds him of the
underline in menu bars when holding down alt. I suggested we do
something similar in LLDB by underlying the letter in the description.
https://discourse.llvm.org/t/should-we-remove-the-capital-letter-in-option-helps/87816
Adds a `--defaults`/`-d` flag to `settings show`. This mode will _optionally_ show a
setting's default value. In other words, this does not always print a default value for
every setting.
A default value is not shown when the current value _is_ the default.
Note: some setting types do not print empty or invalid values. For these setting types,
if the default value is empty or invalid, the same elision logic is applied to printing
the default value.
This fixes a few bugs, effectively through a fallback to `p` when `po` fails.
The motivating bug this fixes is when an error within the compiler causes `po` to fail.
Previously when that happened, only its value (typically an object's address) was
printed – and problematically, no compiler diagnostics were shown. With this change,
compiler diagnostics are shown, _and_ the object is fully printed (ie `p`).
Another bug this fixes is when `po` is used on a type that doesn't provide an object
description (such as a struct). Again, the normal `ValueObject` printing is used.
Additionally, this also improves how lldb handles an object description method that
fails in some way. Now an error will be shown (it wasn't before), and the value will be
printed normally.
Previously, when dwim-print finds a frame variables, it returns immediately after
calling `Dump`, even if `Dump` returns an error. This is most likely to happen when
evaluating an object description, ie `po`.
This changes dwim-print to continue on to expression evaluation when `Dump`ing a
variable returns an error . This is to allow for diagnostics that match `expression`.