This changes `DenseMapInfo<UUID>::getTombstoneKey()` to return a 1-byte
`{0xFF}` sentinel instead of the empty, default constructed UUID().
Returning the same key for the empty and tombstone value apparently
violates the `DenseMap` invariant.
Fixes a crash with the following alias, which I use for printing the
contents of pointer variables:
```
command alias vp v -P1
```
At some point in the recent-ish past, parsing this alias has started
crashing lldb. The problem is code that assumes the option and its value
are separate. This assumption causes an index past the end of a vector.
This fix changes `FindArgumentIndexForOption`. The function now returns
a pair of indexes, the first index is the option, the second index is
the index of the value. In the case of joined options like `-P1`, the
two indexes are the same.
LLDB automatically discovers, but doesn't automatically load, scripts in
the dSYM bundle. This is to prevent running untrusted code. Users can
choose to import the script manually or toggle a global setting to
override this policy. This isn't a great user experience: the former
quickly becomes tedious and the latter leads to decreased security.
This PR offers a middle ground that allows LLDB to automatically load
scripts from trusted dSYM bundles. Trusted here means that the bundle
was signed with a certificate trusted by the system. This can be a
locally created certificate (but not an ad-hoc certificate) or a
certificate from a trusted vendor.
This patch is motivated by
https://github.com/llvm/llvm-project/pull/189943, where we would like to
print the "these module scripts weren't loaded" warning for *all*
modules batched together. I.e., we want to print the warning *after* all
the script loading attempts, not from within each attempt.
To do so we want to hoist the `ReportWarning` calls in
`Module::LoadScriptingResourceInTarget` out into the callsites. But if
we do that, the callers have to remember to print the warnings. To avoid
this, we redirect all callsites to use
`ModuleList::LoadScriptingResourceInTarget`, which will be responsible
for printing the warnings.
To avoid future accidental uses of
`Module::LoadScriptingResourceInTarget` I moved the API into
`ModuleList` and made it `private`.
The only difference between them is that OptionalBool's third state
is "unknown" and LazyBool's is "calculate". We don't need to tell
the difference in a single context, so I've made a new eLazyBoolDontKnow
which is an alias of eLazyBoolCalculate.
This patch changes the `Platform::LocateXXX` to return a map from
`FileSpec` to `LoadScriptFromSymFile` enum.
This is needed for https://github.com/llvm/llvm-project/pull/188722,
where I intend to set `LoadScriptFromSymFile` per-module.
By default the `Platform::LocateXXX` set the value to whatever the
target's current `target.load-script-from-symbol-file` is set to. In
https://github.com/llvm/llvm-project/pull/188722 we'll allow overriding
this per-target setting on a per-module basis.
Drive-by:
* Added logging when we fail to load a script.
In preparation for updating DIL to handle assignments, this adds a
member variable to the DIL Interpreter indicating whether or not
updating program variables is allowed. For invocations from the LLDB
command prompt (through "frame variable") we want to allow it, but from
other places we might not. Therefore we also add new StackFrame
ExpressionPathOption, eExpressionPathOptionsAllowVarUpdates, which we
add to calls from CommandObjectFrame, and which is checked in
GetValueForVariableExpressionPath. Finally, we also add a parameter,
can_update_vars, with a default value of true, to
ValueObject::SetValueFromInteger, as that will be the main function used
to by assignment in DIL.
By turning SetMemoryTagged into a builder method (returns a reference to
self). Then only using that in the tests that need to change the default
of "don't know".
Nothing passes anything but the default value here. Code that wants to
set it is starting with a default constructed info, and filling in the
fields one by one (the gdb-remote client for example).
Meaning a method on an object, which returns a reference to self.
I am doing this because it was pointed out to me that MemoryRegionInfo
has lots of construction paramaters, and most of the time, we want the
default value for most of the things.
So now we can do:
MemoryRegionInfo(...); // Shadow stack is "don't know".
MemoryRegionInfo(...).SetIsShadowStack(eNo) // Shadow stack is "no".
Which removes one parameter from every use of the constructor.
Along the way I realised that the shadow stack "ss" flag is only tested
by the Guarded Control Stack tests, which only run on specific Arm
hardware. I've added a new "ss" test to LinuxProcMapsTest, which will
run on any system.
This plugin creates types based on information from target XML, which is
parsed only once per session. It has internal logic to reuse created
types, but the plugin itself was being remade every time a type was
requested.
SetPrivateRunLockToRunning incorrectly delegated to
SetPrivateRunLockToStopped instead of SetPrivateRunLockToRunning,
causing the private run lock to never transition to the running state on
process resume.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
In `internalConsole` mode (especially in VSCode), lldb-dap should not
use the ConPTY to read the process' output. This is because the
internalConsole is not a real terminal, there is no reason to use
terminal emulation, which will add arbitrary line returns to the output.
Instead, this patch introduces the `eLaunchFlagUsePipes` flag in
ProcessLaunchInfo which tells ProcessLaunchWindows to use regular pipes
instead of a ConPTY to get the stdin and stdout of the debuggee.
The result is that output which is supposed to be on a single line is
properly rendered.
---
The following example is when debugging a program through lldb-dap on
Windows. The program prints the numbers 0 through 999 on a single line.
# Before
<img width="2214" height="672" alt="Screenshot 2026-03-13 at 17 07 35"
src="https://github.com/user-attachments/assets/26292d11-2288-46ee-a6d2-0b66bfa41288"
/>
The line is split if it's longer than 80 characters (default terminal
size).
# After
<img width="2215" height="689" alt="Screenshot 2026-03-13 at 17 12 39"
src="https://github.com/user-attachments/assets/c9cad9af-b1ce-4c7b-91d5-f684e48e64ca"
/>
The line is correctly printed as a single line.
rdar://172491166
While here:
* Move the constructor to the public section. Almost all ThreadPlan
classes have public constructors.
* Use `std::make_shared()`. It is modern and more efficient.
`lldb-private-types.h` includes `lldb-private.h`, which in turn includes
`lldb-private-types.h`. Because of that, `lldb-public.h` included by
`lldb-private.h` after `lldb-private-types.h` is not actually included.
The practical consequence of this is that types defined in
`lldb-public-types.h` (for example, `addr_t` needed downstream) are not
available in `lldb-private-types.h`.
Fix this by "including what you use", which is `lldb-types.h`.
- it is always passed as zero
- a lot of plugins aren't using it correctly
- the data extractor class already has the capability to look at a
subset of bytes
After this change, Address::SetSection() had only one use left (in a
unit test) and was removed. Address::ClearSection() had no uses, now
also removed. (It is unlikely that someone needs to change the section
without simultaneously changing the section offset, and for that we have
a constructor.)
This is to highlight places where we (probably unintentionally)
construct an `Address` object from an already resolved address, making
it unresolved again.
See the changes in `DynamicLoaderDarwin.cpp` for a quick example.
Also, use this constructor instead of `Address(lldb::addr_t file_addr,
const SectionList *section_list)` when `section_list` is `nullptr`.
Avoids manual memory management.
Uses `shared_ptr` instead of `unique_ptr` because we store references to
the current thread in a backup variable.
Simplifies the private thread `is_secondary` semantics by providing a
backup storage for the current thread instead of a boolean value with a
contract to manage the backup separately.
When a scripted frame provider calls back into the thread's frame
machinery (e.g. via HandleCommand or EvaluateExpression), two problems
arise:
1. GetStackFrameList() re-enters the SyntheticStackFrameList
construction, causing infinite recursion.
2. ClearStackFrames() tries to read-lock the StackFrameList's
shared_mutex that is already write-locked by GetFramesUpTo,
causing a deadlock.
This patch fixes those issues by tracking when a provider is actively
fetching frames via a per-host-thread map (m_provider_frames_by_thread)
keyed by HostThread. The map is pushed/popped in
SyntheticStackFrameList::FetchFramesUpTo before calling into the
provider. GetStackFrameList() checks it to route re-entrant calls:
- The provider's own host thread gets the parent frame list, preventing
circular dependency when get_frame_at_index calls back into
GetFrameAtIndex.
- The private state thread also gets the parent frame list, preventing
deadlock when a provider calls EvaluateExpression (which needs the
private state thread to process events).
- Other host threads proceed normally and block on the frame list mutex
until the provider finishes, getting the correct synthetic result.
ClearStackFrames() returns early if any provider is active, since the
frame state is shared and tearing it down while a provider is
mid-construction is both unnecessary and unsafe.
rdar://171558394
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
Some plugins were returning the number of specifications they have
added, while others were returning the total final number. Particularly
devious plugins (Minidump) were clearing the specification list
altogether. This resulted in nondeterministic failures (depending on
plugin ininitialization order) in TestSBModule.
This PR defines the problem away by having each plugin only return the
specifications it is responsible for. If the caller wants to merge them,
it is free to do so. This *might* be slighly less efficient, but this is
hardly hot code.
I'm not touching the ObjectFile::GetModuleSpecifications function (the
caller of all these functions) as the PR is big enough, although the
same approach might be warranted there as well.
Fixes https://github.com/llvm/llvm-project/issues/178625.
Depends on:
* https://github.com/llvm/llvm-project/pull/187229
(only second commit and onwards are relevant)
This patch implements the base infrastructure described in this [RFC re.
Moving libc++ data-formatters out of
LLDB](https://discourse.llvm.org/t/rfc-lldb-moving-libc-data-formatters-out-of-lldb/89591)
The intention is to provide vendors with a way to pre-configure a set of
paths that LLDB can automatically ingest formatter scripts from.
Three main changes:
1. Adds a CMake variable `LLDB_SAFE_AUTO_LOAD_PATHS` which is a
semi-colon separated list of paths. This is intended to be set by
vendors when building LLDB for distribution.
2. Adds a setting that only exists in asserts mode called
`testing.safe-auto-load-paths` which allows setting the paths without a
CMake configuration. Used for local development and, more crucially, the
shell and unit tests
3. Adds a `LocateScriptingResourcesFromSafePaths` which
`Platform::LocateExecutableScriptingResources` calls by default (and
hence used by all platforms). I add a
`LocateExecutableScriptingResourcesImpl` that platforms can override if
they have platform-specific resource script locations (e.g., dSYMs on
Darwin).
Whenever we load an image, we check the safe path (starting with the
last appended path) for a directory called
`/safe/path/to/<module>/<module>.py`. If such script exists, we import
it as a Python module. If not, we move on to the next safe path.
Currently the default for `LLDB_SAFE_AUTO_LOAD_PATHS` is empty.
Eventually the plan is to make those point to the libc++ installation
(where the formatters will live) depending on platform/vendor. For macOS
we'll add a special `$SDK_ROOT` that can be used in the path variable,
which `LocateScriptingResourcesFromSafePaths` will resolve to an actual
SDK path.
*AI Usage*:
* Claude assisted with the CMake machinery which I then reviewed and
cleaned up. I'm not sure this is the most idiomatic way of letting a
user provide lists of paths, but I couldn't find a better way.
* Wrote the basic auto-load Shell tests myself and asked claude to stamp
out a bunch more for different scenarios. Reviewed and cleaned those up
myself.
This changes the inputs to `update`. It's now the data stack that was
the result of `@init`. This makes `update` more predictable, as its
inputs are the same between the first call and the Nth call.
**Description:**
Adds `IsMemberDataPointerType()` to CompilerType / TypeSystem /
TypeSystemClang, mirroring the existing `IsMemberFunctionPointerType()`.
LLDB already has `IsMemberFunctionPointerType()` to identify member
function pointers but no counterpart for member data pointers. The only
way to check for member data pointers was the indirect `GetTypeClass()
== eTypeClassMemberPointer && !IsMemberFunctionPointerType()`, which is
awkward.
This pr is split out from a larger [fix,
186629](https://github.com/llvm/llvm-project/pull/186629) for LLDB
mishandling non-type template parameters (NTTPs) of pointer-to-member
types, where cleanly distinguishing member data pointers from member
function pointers is needed. The new API delegates to clang's
`QualType::isMemberDataPointerType()` via the same I`sTypeImpl` pattern
used by `IsMemberFunctionPointerType`.
**Test Plan:**
Added `TestIsMemberDataPointerType` to `TestTypeSystemClang.cpp` that
verifies:
`int S::*` → `IsMemberDataPointerType() = true`,
`IsMemberFunctionPointerType() = false`
`void (S::*)()` → `IsMemberDataPointerType() = false`,
`IsMemberFunctionPointerType() = true`
`int * (regular pointer)` → both false
`int (non-pointer)`→ both false
Fetch the size of the shared cache address range in VM in the inferior
process and return it, if possible. This allows for a simple call to
DynamicLoader::GetSharedCacheInformation to get the virtual address
extent of the shared cache in the inferior. It's a minor addition to the
method that fetches the shared cache filepath from the inferior, plus
piping it up through lldb's layers.
---------
Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
In preparation for https://github.com/llvm/llvm-project/pull/187031
The `SanitizedScriptingModuleName` will be re-used from `Platform` (in
addition to `PlatformDarwin` where it currently lives). To do that we'll
need to move it to a common place. `ScriptInterpreter` seems like the
most natural place for this to live.
I introduced a new virtual `GetSanitizedScriptingModuleName` that
`ScriptInterpreter`s can override in the future if they have their own
sanitization logic. I made the default implementation the one we've been
using for Python because that way the unit-tests that currently mock the
`ScriptInterpreter` don't need to copy the implementation.
Also made `WarnIfInvalidUnsanitizedScriptExists` a protected static
function on `Platform` because it didn't seem right for that to also
live in `ScriptInterpreter`.
lldb had three preprocessor defines for logging,
LLDB_LOG - formatv style argument
LLDB_LOGF - printf style argument
LLDB_LOGV - formatv style argument, only when verbose enabled
If you weren't looking at Log.h and the definition of these three, and
wanted to log something with formatv, it was easy to use LLDB_LOGV by
accident. We just had a situation where an important log statement
wasn't logging and it turned out to be this. This is fragile if you
aren't looking at the header directly, so I'd like to make this more
explicit. My proposal:
LLDB_LOG - formatv style argument
LLDB_LOG_VERBOSE - formatv style argument, only when verbose enabled
LLDB_LOGF - printf style argument
LLDB_LOGF_VERBOSE - printf style argument, only when verbose enabled
The new fouth one is to remove several places where we do `if (log &&
log->GetVerbose()) LLDB_LOGF (...)` in the sources today, and make both
styles consistent.
This PR implements that change, mechanically changing all LLDB_LOGV's to
LLDB_LOG_VERBOSE.
It also updates many of the `if (log && log->GetVerbose()) LLDB_LOGF`'s.
Some uses of this conditional expression do extra calculations in
addition to logging, and so those were left as-is so we're not doing
throwaway work when running without verbose logging.
There were many instances throughout lldb where callers are still doing
`if (log) LLDB_LOG*(...)`, a remnant of when all calls were to the `Log`
object's `Printf()` method, and you had to check if your local Log*
pointer was non-nullptr before calling the method. I removed those,
again keeping ones where work for logging is done in the block of code.
The code changes are all mechanical and uninteresting, but the question
of whether this naming change is widely agreed on is maybe worth
discussing.
Add a LoadCompilationPrefixMap() helper in SymbolFile::FindPlugin that
walks up from the symbol file's directory looking for a
compilation-prefix-map.json file. When found, each key→value entry is
applied to the module's source path mapping list, allowing LLDB to
resolve source file paths that were rewritten by -fdebug-prefix-map at
build time without requiring manual `settings set target.source-map`.
The JSON file format maps fake paths (as written into debug info) back
to their real on-disk counterparts:
{ "/fake/srcdir": "/real/srcdir" }
Directory results are cached so the filesystem is walked at most once
per unique directory across all modules loaded in a session.
Also apply the module's source path remappings in
SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex when constructing
compile units from N_SO stabs. This mirrors what MakeAbsoluteAndRemap
does for the dSYM case so that fake paths baked into the debug map are
transparently resolved to real paths.
rdar://84824567
Assisted-By: Claude
In #186001, I said the last large chunk of downstream PtrAuth code in
LLDB was the expression evaluator support. However, that wasn't
accurate, as we also have changes to thread this through ValueObject.
I'm in the process of making `LoadScriptingResources` interactively ask
a user whether to load a script. I'd like to turn the existing warning
into the prompt. The simplest way to achieve this is to not print into a
`feedback_stream` parameter, and instead create a prompt right there.
This patch removes the `feedback_stream` parameter and emits a
`ReportWarning` instead. If we get around to adding the prompt instead
of the warning, those changes will be simpler to review. But even if we
don't end up replacing the warning with a prompt, moving away from
output parameters and towards more structured error reporting is a
nice-to-have (e.g., the `warning` prefix is now colored, IDEs have more
flexibility on how to present the warning, etc.).
For a command-line user nothing should change with this patch (apart
from `warning:` being highlighted).
Currently these functions take a target pointer. In Cross-language
projects this means it's down to chance what typesystem the resulting
value will be in, since the implementation returns the first scratch
type system in the target, which depends on the order of images and
their implementation language.
By passing in an execution context the selected frame is used to
determine the typesystem, which is usually the expected outcome when
using DIL.
This should be entirely NFC for Clang-only LLDBs, but is a necessity for
LLDBs with additional type system plugins such as the Swift plugin.
Assisted by Claude to patch the call sites.
This makes the constructions of string errors more concise and more
consistent, mainly by removing the `inconvertibleErrorCode()`.
Additional changes replace `createStringError(formatv(...), ...)` with
`createStringErrorV(...)`.
Assisted-by: Claude
We already catch missing calls to SystemLifetimeManager::Terminate, but
not for Initialize. This adds the missing assert and also makes sure it
behaves correctly when initializing and terminating more than once,
which is now supported.
Host::RunShellCommand takes a std::string *command_output argument and a
bool hide_stderr=false defaulted argument. If the shell command returns
stderr and stdout text, it is intermixed in the same command_output,
unless hide_stderr=true.
In SymbolLocatorDebugSymbols::DownloadObjectAndSymbolFile we call an
external program to find a binary and dSYM by uuid, and the external
program returns a plist (xml) output. In some cases, it printed a
(harmless) warning message to stderr, and then a complete plist output
to stdout. We attempt to parse the combination of these two streams, and
the parse fails - we don't get the output.
This patch removes hide_stderr and instead adds a `std::string
*separated_error_output` argument. If `separated_error_output` is
nullptr, output and error texts are returned combined in the
`command_output` argument. If a std::string object address is provided
for `separated_error_output`, then standard error output is separated
into this string. A caller which wants the old `hide_stderr=true`
behavior should pass a throwaway std::string object to `RunShellCommand`
and ignore it.
rdar://168621579
ObjectFile::FindPlugin iterates over plugins to find one that can handle
the binary provided. It is currently sending the one DataExtractorSP to
each subclass, but some subclasses may modify this DataExtractor during
their processing, e.g. calling DataExtractor::SetData on it, and I think
it is safer to isolate these with a copy of the DataExtractor so the
order the plugins are tried cannot possibly change behavior.