[Lldb-commits] [lldb] Ensure that the Synthetic children of a ValueObject are managed by their parents ClusterManager (PR #192561)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Apr 16 15:47:38 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: jimingham
<details>
<summary>Changes</summary>
A very common pattern in our synthetic child providers was to make the child ValueObject using ValueObjectConstResult::Create or some form of the static ValueObject::CreateValueObjectFrom*** methods, and store and hand that out as the child. Doing that creates a "root" ValueObject whose lifecycle is not linked to the lifecycle of the ValueObject it is a child of. And that means it is possible that either the child or the parent could have gotten destroyed when the other ValueObject gets asked a question about it.
For the most part this doesn't happen because there are usually enough other shared pointer references binding the two to keep both sides alive. But we have gotten a small but steady stream of reports for years now of crashes where a ValueObject accesses its ClusterManager but that has already been deleted. I've never been able to find a reproducible case of this, but one plausible cause is that we are violating the contract that "all the children of a ValueObject have coterminous lifespans, enforced by the ClusterManager". So it is unsurprising that they might sometimes not stay alive as long as they should.
This patch addresses that by providing a way to use these static create methods but passing in the ClusterManager to be used, and adds or modifies where extant the CreateChildValueObjectFrom*** methods to pass in the parent manager.
This patch is not complete. It turns out that routing the ClusterManager from CreateValueObjectFromExpression all the way to where the expression result VO is made is quite intrusive, and would have made this already quite large (though largly mechanical) patch become unweildy. Since I am mostly concerned about synthetic child providers, and we discourage using expressions for them, I think that's an acceptable separation.
I also added a test where the ValueObjectSynthetic hands out its children, checking whether the child being handed out is in fact owned by the parent handing it out. It is controlled by a setting (target.check-vo-ownership) which is currently off by default - since I can't provide a way to do this correctly for expressions yet. But I turn it on in the testsuite. That's the real testing strategy for this patch, since its goal is to ensure that all the children we hand out are managed by their parents. I didn't put an equivalent check in ValueObjectVariable because that system really doesn't allow a way to do this incorrectly.
I also fixed some of the tests that were making children using CreateValueObjectFromExpression to make their children with CreateValueObjectFromData instead. I could have opted the tests out of the check, but using the expression parser to do this work is not best practice, so I didn't want to leave bad examples around. I left one case that does do it with expressions, however, so we still have a test for that not-recommended but people do it anyway path.
---
Patch is 71.33 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/192561.diff
40 Files Affected:
- (modified) lldb/include/lldb/DataFormatters/TypeSynthetic.h (+3-3)
- (modified) lldb/include/lldb/Target/Target.h (+4)
- (modified) lldb/include/lldb/ValueObject/ValueObject.h (+94-10)
- (modified) lldb/include/lldb/ValueObject/ValueObjectConstResult.h (+14-7)
- (modified) lldb/packages/Python/lldbsuite/test/lldbtest.py (+1)
- (modified) lldb/source/API/SBValue.cpp (+4-4)
- (modified) lldb/source/DataFormatters/TypeSynthetic.cpp (+10-9)
- (modified) lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp (+4-4)
- (modified) lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp (+1-1)
- (modified) lldb/source/Plugins/Language/CPlusPlus/GenericInitializerList.cpp (+1-1)
- (modified) lldb/source/Plugins/Language/CPlusPlus/GenericList.cpp (+5-5)
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxProxyArray.cpp (+2-2)
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp (+1-1)
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp (+1-1)
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp (+1-1)
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxValarray.cpp (+1-1)
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp (+3-3)
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp (+2-2)
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibStdcppSpan.cpp (+1-1)
- (modified) lldb/source/Plugins/Language/CPlusPlus/MsvcStlDeque.cpp (+1-1)
- (modified) lldb/source/Plugins/Language/CPlusPlus/MsvcStlSpan.cpp (+1-1)
- (modified) lldb/source/Plugins/Language/CPlusPlus/MsvcStlVector.cpp (+3-3)
- (modified) lldb/source/Plugins/Language/ObjC/NSArray.cpp (+2-2)
- (modified) lldb/source/Plugins/Language/ObjC/NSDictionary.cpp (+6-6)
- (modified) lldb/source/Plugins/Language/ObjC/NSError.cpp (+1-1)
- (modified) lldb/source/Plugins/Language/ObjC/NSException.cpp (+40-21)
- (modified) lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp (+12-13)
- (modified) lldb/source/Plugins/Language/ObjC/NSSet.cpp (+3-3)
- (modified) lldb/source/Plugins/Language/ObjC/NSString.cpp (+1-1)
- (modified) lldb/source/Target/Target.cpp (+11)
- (modified) lldb/source/Target/TargetProperties.td (+3)
- (modified) lldb/source/ValueObject/ValueObject.cpp (+52-18)
- (modified) lldb/source/ValueObject/ValueObjectConstResult.cpp (+57-21)
- (modified) lldb/source/ValueObject/ValueObjectConstResultImpl.cpp (+1-1)
- (modified) lldb/source/ValueObject/ValueObjectSynthetic.cpp (+6-1)
- (modified) lldb/test/API/commands/expression/issue_11588/Test11588.py (+3-1)
- (modified) lldb/test/API/functionalities/data-formatter/callback-matching/TestDataFormatterCallbackMatching.py (+1)
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-python-synth/ftsp.py (+4-2)
- (modified) lldb/test/API/functionalities/data-formatter/type-synth-wants-deref/provider.py (+5-1)
- (modified) lldb/test/API/python_api/formatters/synth.py (+4-1)
``````````diff
diff --git a/lldb/include/lldb/DataFormatters/TypeSynthetic.h b/lldb/include/lldb/DataFormatters/TypeSynthetic.h
index 7bcf12f334fde..c2348e03b34b8 100644
--- a/lldb/include/lldb/DataFormatters/TypeSynthetic.h
+++ b/lldb/include/lldb/DataFormatters/TypeSynthetic.h
@@ -88,16 +88,16 @@ class SyntheticChildrenFrontEnd {
protected:
lldb::ValueObjectSP
- CreateValueObjectFromExpression(llvm::StringRef name,
+ CreateChildValueObjectFromExpression(llvm::StringRef name,
llvm::StringRef expression,
const ExecutionContext &exe_ctx);
lldb::ValueObjectSP
- CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
+ CreateChildValueObjectFromAddress(llvm::StringRef name, uint64_t address,
const ExecutionContext &exe_ctx,
CompilerType type, bool do_deref = true);
- lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name,
+ lldb::ValueObjectSP CreateChildValueObjectFromData(llvm::StringRef name,
const DataExtractor &data,
const ExecutionContext &exe_ctx,
CompilerType type);
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 67f373aa5a325..8fdf5bbdd89ae 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -284,6 +284,10 @@ class TargetProperties : public Properties {
void SetDebugUtilityExpression(bool debug);
bool GetDebugUtilityExpression() const;
+
+ void SetCheckValueObjectOwnership(bool check);
+
+ bool GetCheckValueObjectOwnership() const;
std::optional<LoadScriptFromSymFile>
GetAutoLoadScriptsForModule(llvm::StringRef module_name) const;
diff --git a/lldb/include/lldb/ValueObject/ValueObject.h b/lldb/include/lldb/ValueObject/ValueObject.h
index cf69a713f1366..d9e63ff380605 100644
--- a/lldb/include/lldb/ValueObject/ValueObject.h
+++ b/lldb/include/lldb/ValueObject/ValueObject.h
@@ -705,16 +705,25 @@ class ValueObject {
llvm::Error Dump(Stream &s, const DumpValueObjectOptions &options);
+ /// The following static routines create "Root" ValueObjects if parent is
+ /// null. If it is a valid ValueObject, the new ValueObject is managed by the
+ /// ValueObjectManager of the parent object.
+ /// However, if you are creating a ValueObject in a Synthetic Child Provider,
+ /// use the method CreateChildValueObjectFrom... instead for that purpose.
+ /// That will ensure the right parent is passed in.
+
static lldb::ValueObjectSP
CreateValueObjectFromExpression(llvm::StringRef name,
llvm::StringRef expression,
- const ExecutionContext &exe_ctx);
+ const ExecutionContext &exe_ctx,
+ ValueObject *parent = nullptr);
static lldb::ValueObjectSP
CreateValueObjectFromExpression(llvm::StringRef name,
llvm::StringRef expression,
const ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions &options);
+ const EvaluateExpressionOptions &options,
+ ValueObject *parent = nullptr);
/// Given an address either create a value object containing the value at
/// that address, or create a value object containing the address itself
@@ -723,40 +732,113 @@ class ValueObject {
static lldb::ValueObjectSP
CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
const ExecutionContext &exe_ctx,
- CompilerType type, bool do_deref = true);
+ CompilerType type, bool do_deref = true,
+ ValueObject *parent = nullptr);
static lldb::ValueObjectSP
CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data,
- const ExecutionContext &exe_ctx, CompilerType type);
+ const ExecutionContext &exe_ctx, CompilerType type,
+ ValueObject *parent = nullptr);
/// Create a value object containing the given APInt value.
static lldb::ValueObjectSP
CreateValueObjectFromAPInt(const ExecutionContext &exe_ctx,
const llvm::APInt &v, CompilerType type,
- llvm::StringRef name);
+ llvm::StringRef name,
+ ValueObject *parent = nullptr);
/// Create a value object containing the given APFloat value.
static lldb::ValueObjectSP
CreateValueObjectFromAPFloat(const ExecutionContext &exe_ctx,
const llvm::APFloat &v, CompilerType type,
- llvm::StringRef name);
+ llvm::StringRef name,
+ ValueObject *parent = nullptr);
/// Create a value object containing the given Scalar value.
static lldb::ValueObjectSP
CreateValueObjectFromScalar(const ExecutionContext &exe_ctx, Scalar &s,
- CompilerType type, llvm::StringRef name);
+ CompilerType type, llvm::StringRef name,
+ ValueObject *parent = nullptr);
/// Create a value object containing the given boolean value.
static lldb::ValueObjectSP
CreateValueObjectFromBool(const ExecutionContext &exe_ctx,
lldb::TypeSystemSP typesystem, bool value,
- llvm::StringRef name);
+ llvm::StringRef name,
+ ValueObject *parent = nullptr);
/// Create a nullptr value object with the specified type (must be a
/// nullptr type).
static lldb::ValueObjectSP
CreateValueObjectFromNullptr(const ExecutionContext &exe_ctx,
- CompilerType type, llvm::StringRef name);
+ CompilerType type, llvm::StringRef name,
+ ValueObject *parent = nullptr);
+
+ /// These are the appropriate routines to make a ValueObject that get managed
+ /// by this ValueObject (and all the other members of its Cluster).
+ lldb::ValueObjectSP
+ CreateChildValueObjectFromExpression(llvm::StringRef name,
+ llvm::StringRef expression,
+ const ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options) {
+ return CreateValueObjectFromExpression(name, expression, exe_ctx, options, this);
+ }
+
+ /// Given an address either create a value object containing the value at
+ /// that address, or create a value object containing the address itself
+ /// (pointer value), depending on whether the parameter 'do_deref' is true or
+ /// false.
+ lldb::ValueObjectSP
+ CreateChildValueObjectFromAddress(llvm::StringRef name, uint64_t address,
+ const ExecutionContext &exe_ctx,
+ CompilerType type, bool do_deref = true) {
+ return CreateValueObjectFromAddress(name, address, exe_ctx, type, do_deref, this);
+ }
+
+ lldb::ValueObjectSP
+ CreateChildValueObjectFromData(llvm::StringRef name, const DataExtractor &data,
+ const ExecutionContext &exe_ctx, CompilerType type) {
+ return CreateValueObjectFromData(name, data, exe_ctx, type, this);
+ }
+
+ /// Create a value object containing the given APInt value.
+ lldb::ValueObjectSP
+ CreateChildValueObjectFromAPInt(const ExecutionContext &exe_ctx,
+ const llvm::APInt &v, CompilerType type,
+ llvm::StringRef name) {
+ return CreateValueObjectFromAPInt(exe_ctx, v, type, name, this);
+ }
+
+ /// Create a value object containing the given APFloat value.
+ lldb::ValueObjectSP
+ CreateChildValueObjectFromAPFloat(const ExecutionContext &exe_ctx,
+ const llvm::APFloat &v, CompilerType type,
+ llvm::StringRef name) {
+ return CreateValueObjectFromAPFloat(exe_ctx, v, type, name, this);
+ }
+
+ /// Create a value object containing the given Scalar value.
+ lldb::ValueObjectSP
+ CreateChildValueObjectFromScalar(const ExecutionContext &exe_ctx, Scalar &s,
+ CompilerType type, llvm::StringRef name) {
+ return CreateValueObjectFromScalar(exe_ctx, s, type, name, this);
+ }
+
+ /// Create a value object containing the given boolean value.
+ lldb::ValueObjectSP
+ CreateChildValueObjectFromBool(const ExecutionContext &exe_ctx,
+ lldb::TypeSystemSP typesystem, bool value,
+ llvm::StringRef name) {
+ return CreateValueObjectFromBool(exe_ctx, typesystem, value, name, this);
+ }
+
+ /// Create a nullptr value object with the specified type (must be a
+ /// nullptr type).
+ lldb::ValueObjectSP
+ CreateChildValueObjectFromNullptr(const ExecutionContext &exe_ctx,
+ CompilerType type, llvm::StringRef name) {
+ return CreateValueObjectFromNullptr(exe_ctx, type, name, this);
+ }
lldb::ValueObjectSP Persist();
@@ -891,6 +973,8 @@ class ValueObject {
/// pointing to, and thus also can't know its size. See the comment in
/// Value::m_value for a more thorough explanation of why that is.
llvm::ArrayRef<uint8_t> GetLocalBuffer() const;
+
+ lldb::ValueObjectSP CheckValueObjectOwnership(ValueObject *child);
protected:
typedef ClusterManager<ValueObject> ValueObjectManager;
@@ -935,7 +1019,7 @@ class ValueObject {
ChildrenMap m_children;
size_t m_children_count = 0;
};
-
+
// Classes that inherit from ValueObject can see and modify these
/// The parent value object, or nullptr if this has no parent.
diff --git a/lldb/include/lldb/ValueObject/ValueObjectConstResult.h b/lldb/include/lldb/ValueObject/ValueObjectConstResult.h
index 6fbb15328ee5c..1ddea2bc8b832 100644
--- a/lldb/include/lldb/ValueObject/ValueObjectConstResult.h
+++ b/lldb/include/lldb/ValueObject/ValueObjectConstResult.h
@@ -37,37 +37,44 @@ class ValueObjectConstResult : public ValueObject {
static lldb::ValueObjectSP
Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order,
- uint32_t addr_byte_size, lldb::addr_t address = LLDB_INVALID_ADDRESS);
+ uint32_t addr_byte_size, lldb::addr_t address = LLDB_INVALID_ADDRESS,
+ ValueObjectManager *manager = nullptr);
static lldb::ValueObjectSP
Create(ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
ConstString name, const DataExtractor &data,
- lldb::addr_t address = LLDB_INVALID_ADDRESS);
+ lldb::addr_t address = LLDB_INVALID_ADDRESS,
+ ValueObjectManager *manager = nullptr);
static lldb::ValueObjectSP
Create(ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
ConstString name, const lldb::DataBufferSP &result_data_sp,
lldb::ByteOrder byte_order, uint32_t addr_size,
- lldb::addr_t address = LLDB_INVALID_ADDRESS);
+ lldb::addr_t address = LLDB_INVALID_ADDRESS,
+ ValueObjectManager *manager = nullptr);
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
const CompilerType &compiler_type,
ConstString name, lldb::addr_t address,
AddressType address_type,
- uint32_t addr_byte_size);
+ uint32_t addr_byte_size,
+ ValueObjectManager *manager = nullptr);
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
Value &value, ConstString name,
- Module *module = nullptr);
+ Module *module = nullptr,
+ ValueObjectManager *manager = nullptr);
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
const CompilerType &compiler_type,
Scalar &scalar, ConstString name,
- Module *module = nullptr);
+ Module *module = nullptr,
+ ValueObjectManager *manager = nullptr);
// When an expression fails to evaluate, we return an error
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
- Status &&error);
+ Status &&error,
+ ValueObjectManager *manager = nullptr);
llvm::Expected<uint64_t> GetByteSize() override;
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index f2a9f3bba1993..aacde8265c9f4 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -818,6 +818,7 @@ def setUpCommands(cls):
"settings set use-color false",
# Disable the statusline by default.
"settings set show-statusline false",
+ "settings set target.check-vo-ownership true",
]
# Set any user-overridden settings.
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index a27da7b61f8ea..8fbcecb493721 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -434,7 +434,7 @@ lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
lldb::ValueObjectSP new_value_sp;
if (value_sp) {
ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
- new_value_sp = ValueObject::CreateValueObjectFromExpression(
+ new_value_sp = value_sp->CreateChildValueObjectFromExpression(
name, expression, exe_ctx, options.ref());
if (new_value_sp)
new_value_sp->SetName(ConstString(name));
@@ -456,7 +456,7 @@ lldb::SBValue SBValue::CreateValueFromAddress(const char *name,
if (value_sp && type_impl_sp) {
CompilerType ast_type(type_impl_sp->GetCompilerType(true));
ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
- new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address,
+ new_value_sp = value_sp->CreateChildValueObjectFromAddress(name, address,
exe_ctx, ast_type);
}
sb_value.SetSP(new_value_sp);
@@ -474,7 +474,7 @@ lldb::SBValue SBValue::CreateValueFromData(const char *name, SBData data,
lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
if (value_sp && type_impl_sp) {
ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
- new_value_sp = ValueObject::CreateValueObjectFromData(
+ new_value_sp = value_sp->CreateChildValueObjectFromData(
name, **data, exe_ctx, type_impl_sp->GetCompilerType(true));
new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
}
@@ -508,7 +508,7 @@ lldb::SBValue SBValue::CreateBoolValue(const char *name, bool value) {
"cannot get a type system: {0}");
return {};
}
- return ValueObject::CreateValueObjectFromBool(exe_ctx, *type_system_or_err,
+ return value_sp->CreateChildValueObjectFromBool(exe_ctx, *type_system_or_err,
value, name);
};
sb_value.SetSP(get_new_value());
diff --git a/lldb/source/DataFormatters/TypeSynthetic.cpp b/lldb/source/DataFormatters/TypeSynthetic.cpp
index 5f103ca6ac00a..afcb75ef52529 100644
--- a/lldb/source/DataFormatters/TypeSynthetic.cpp
+++ b/lldb/source/DataFormatters/TypeSynthetic.cpp
@@ -129,31 +129,32 @@ SyntheticChildrenFrontEnd::CalculateNumChildrenIgnoringErrors(uint32_t max) {
return 0;
}
-lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromExpression(
+lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateChildValueObjectFromExpression(
llvm::StringRef name, llvm::StringRef expression,
const ExecutionContext &exe_ctx) {
- ValueObjectSP valobj_sp(
- ValueObject::CreateValueObjectFromExpression(name, expression, exe_ctx));
+ EvaluateExpressionOptions options;
+ ValueObjectSP valobj_sp = m_backend.CreateChildValueObjectFromExpression(name,
+ expression, exe_ctx, options);
if (valobj_sp)
valobj_sp->SetSyntheticChildrenGenerated(true);
return valobj_sp;
}
-lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromAddress(
+lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateChildValueObjectFromAddress(
llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
CompilerType type, bool do_deref) {
- ValueObjectSP valobj_sp(ValueObject::CreateValueObjectFromAddress(
- name, address, exe_ctx, type, do_deref));
+ ValueObjectSP valobj_sp = m_backend.CreateChildValueObjectFromAddress(
+ name, address, exe_ctx, type, do_deref);
if (valobj_sp)
valobj_sp->SetSyntheticChildrenGenerated(true);
return valobj_sp;
}
-lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromData(
+lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateChildValueObjectFromData(
llvm::StringRef name, const DataExtractor &data,
const ExecutionContext &exe_ctx, CompilerType type) {
- ValueObjectSP valobj_sp(
- ValueObject::CreateValueObjectFromData(name, data, exe_ctx, type));
+ ValueObjectSP valobj_sp =
+ m_backend.CreateChildValueObjectFromData(name, data, exe_ctx, type);
if (valobj_sp)
valobj_sp->SetSyntheticChildrenGenerated(true);
return valobj_sp;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
index c49abd48082cd..4cca7aa46abf9 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
@@ -167,11 +167,11 @@ lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::Update() {
/*result_type=*/void_type, args,
/*is_variadic=*/false, /*qualifiers=*/0);
CompilerType coro_func_ptr_type = coro_func_type.GetPointerType();
- ValueObjectSP resume_ptr_sp = CreateValueObjectFromAddress(
+ ValueObjectSP resume_ptr_sp = CreateChildValueObjectFromAddress(
"resume", frame_ptr_addr + 0 * ptr_size, exe_ctx, coro_func_ptr_type);
assert(resume_ptr_sp);
m_children.push_back(std::move(resume_ptr_sp));
- ValueObjectSP destroy_ptr_sp = CreateValueObjectFromAddress(
+ ValueObjectSP destroy_ptr_sp = CreateChildValueObjectFromAddress(
"destroy", frame_ptr_addr + 1 * ptr_size, exe_ctx, coro_func_ptr_type);
assert(destroy_ptr_sp);
m_children.push_back(std::move(destroy_ptr_sp));
@@ -182,11 +182,11 @@ lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::Update() {
// those pointers. We do so to avoid potential very deep recursion in case
// there is a cycle formed between `std::coroutine_handle`s and their
// promises.
- ValueObjectSP promise_ptr_sp = CreateValueObjectFromAddress(
+ ValueObjectSP promise_ptr_sp = CreateChildValueObjectFromAddress(
"promise", frame_ptr_addr + 2 * ptr_size, exe_ctx,
promise_type.GetPointerType(), /*do_deref=*/false);
m_children.push_back(std::move(promise_ptr_sp));
- ValueObjectSP coroframe_ptr_sp = CreateValueObjectFromAddress(
+ ValueObjectSP coroframe_ptr_sp = CreateChildValueObjectFromAddress(
"coro_frame", frame_ptr_addr, exe_ctx, coro_frame_type.GetPointerType(),
/*do_deref=*/false);
m_children.push_back(std::move(coroframe_ptr_sp));
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
index 1d522f0b4a724..d10c307b5256e 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
@@ -126,7 +126,7 @@ ValueObjectSP GenericBitsetFrontEnd::GetChildAtIndex(uint32_t idx) {
uin...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/192561
More information about the lldb-commits
mailing list