diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /lldb/source/Core/ValueObject.cpp | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Notes
Diffstat (limited to 'lldb/source/Core/ValueObject.cpp')
-rw-r--r-- | lldb/source/Core/ValueObject.cpp | 121 |
1 files changed, 82 insertions, 39 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 74176eeace3a..1dd9a6cf62c3 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -22,9 +22,9 @@ #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeFormat.h" #include "lldb/DataFormatters/TypeSummary.h" -#include "lldb/DataFormatters/TypeValidator.h" #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Expression/ExpressionVariable.h" +#include "lldb/Host/Config.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/CompilerType.h" @@ -82,13 +82,12 @@ ValueObject::ValueObject(ValueObject &parent) m_parent(&parent), m_root(nullptr), m_update_point(parent.GetUpdatePoint()), m_name(), m_data(), m_value(), m_error(), m_value_str(), m_old_value_str(), m_location_str(), - m_summary_str(), m_object_desc_str(), m_validation_result(), - m_manager(parent.GetManager()), m_children(), m_synthetic_children(), - m_dynamic_value(nullptr), m_synthetic_value(nullptr), - m_deref_valobj(nullptr), m_format(eFormatDefault), - m_last_format(eFormatDefault), m_last_format_mgr_revision(0), - m_type_summary_sp(), m_type_format_sp(), m_synthetic_children_sp(), - m_type_validator_sp(), m_user_id_of_forced_summary(), + m_summary_str(), m_object_desc_str(), m_manager(parent.GetManager()), + m_children(), m_synthetic_children(), m_dynamic_value(nullptr), + m_synthetic_value(nullptr), m_deref_valobj(nullptr), + m_format(eFormatDefault), m_last_format(eFormatDefault), + m_last_format_mgr_revision(0), m_type_summary_sp(), m_type_format_sp(), + m_synthetic_children_sp(), m_user_id_of_forced_summary(), m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid), m_value_checksum(), m_preferred_display_language(lldb::eLanguageTypeUnknown), @@ -100,6 +99,8 @@ ValueObject::ValueObject(ValueObject &parent) m_did_calculate_complete_objc_class_type(false), m_is_synthetic_children_generated( parent.m_is_synthetic_children_generated) { + m_data.SetByteOrder(parent.GetDataExtractor().GetByteOrder()); + m_data.SetAddressByteSize(parent.GetDataExtractor().GetAddressByteSize()); m_manager->ManageObject(this); } @@ -110,12 +111,12 @@ ValueObject::ValueObject(ExecutionContextScope *exe_scope, m_parent(nullptr), m_root(nullptr), m_update_point(exe_scope), m_name(), m_data(), m_value(), m_error(), m_value_str(), m_old_value_str(), m_location_str(), m_summary_str(), m_object_desc_str(), - m_validation_result(), m_manager(), m_children(), m_synthetic_children(), + m_manager(), m_children(), m_synthetic_children(), m_dynamic_value(nullptr), m_synthetic_value(nullptr), m_deref_valobj(nullptr), m_format(eFormatDefault), m_last_format(eFormatDefault), m_last_format_mgr_revision(0), m_type_summary_sp(), m_type_format_sp(), m_synthetic_children_sp(), - m_type_validator_sp(), m_user_id_of_forced_summary(), + m_user_id_of_forced_summary(), m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type), m_value_checksum(), m_preferred_display_language(lldb::eLanguageTypeUnknown), @@ -126,6 +127,14 @@ ValueObject::ValueObject(ExecutionContextScope *exe_scope, m_is_getting_summary(false), m_did_calculate_complete_objc_class_type(false), m_is_synthetic_children_generated(false) { + if (exe_scope) { + TargetSP target_sp(exe_scope->CalculateTarget()); + if (target_sp) { + const ArchSpec &arch = target_sp->GetArchitecture(); + m_data.SetByteOrder(arch.GetByteOrder()); + m_data.SetAddressByteSize(arch.GetAddressByteSize()); + } + } m_manager = new ValueObjectManager(); m_manager->ManageObject(this); } @@ -133,6 +142,58 @@ ValueObject::ValueObject(ExecutionContextScope *exe_scope, // Destructor ValueObject::~ValueObject() {} +void ValueObject::UpdateChildrenAddressType() { + Value::ValueType value_type = m_value.GetValueType(); + ExecutionContext exe_ctx(GetExecutionContextRef()); + Process *process = exe_ctx.GetProcessPtr(); + const bool process_is_alive = process && process->IsAlive(); + const uint32_t type_info = GetCompilerType().GetTypeInfo(); + const bool is_pointer_or_ref = + (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0; + + switch (value_type) { + case Value::eValueTypeFileAddress: + // If this type is a pointer, then its children will be considered load + // addresses if the pointer or reference is dereferenced, but only if + // the process is alive. + // + // There could be global variables like in the following code: + // struct LinkedListNode { Foo* foo; LinkedListNode* next; }; + // Foo g_foo1; + // Foo g_foo2; + // LinkedListNode g_second_node = { &g_foo2, NULL }; + // LinkedListNode g_first_node = { &g_foo1, &g_second_node }; + // + // When we aren't running, we should be able to look at these variables + // using the "target variable" command. Children of the "g_first_node" + // always will be of the same address type as the parent. But children + // of the "next" member of LinkedListNode will become load addresses if + // we have a live process, or remain a file address if it was a file + // address. + if (process_is_alive && is_pointer_or_ref) + SetAddressTypeOfChildren(eAddressTypeLoad); + else + SetAddressTypeOfChildren(eAddressTypeFile); + break; + case Value::eValueTypeHostAddress: + // Same as above for load addresses, except children of pointer or refs + // are always load addresses. Host addresses are used to store freeze + // dried variables. If this type is a struct, the entire struct + // contents will be copied into the heap of the + // LLDB process, but we do not currently follow any pointers. + if (is_pointer_or_ref) + SetAddressTypeOfChildren(eAddressTypeLoad); + else + SetAddressTypeOfChildren(eAddressTypeHost); + break; + case Value::eValueTypeLoadAddress: + case Value::eValueTypeScalar: + case Value::eValueTypeVector: + SetAddressTypeOfChildren(eAddressTypeLoad); + break; + } +} + bool ValueObject::UpdateValueIfNeeded(bool update_format) { bool did_change_formats = false; @@ -195,6 +256,7 @@ bool ValueObject::UpdateValueIfNeeded(bool update_format) { SetValueIsValid(success); if (success) { + UpdateChildrenAddressType(); const uint64_t max_checksum_size = 128; m_data.Checksum(m_value_checksum, max_checksum_size); } else { @@ -241,11 +303,10 @@ bool ValueObject::UpdateFormatsIfNeeded() { SetValueFormat(DataVisualization::GetFormat(*this, eNoDynamicValues)); SetSummaryFormat( DataVisualization::GetSummaryFormat(*this, GetDynamicValueType())); -#ifndef LLDB_DISABLE_PYTHON +#if LLDB_ENABLE_PYTHON SetSyntheticChildren( DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType())); #endif - SetValidator(DataVisualization::GetValidator(*this, GetDynamicValueType())); } return any_change; @@ -526,6 +587,10 @@ ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name, std::vector<uint32_t> child_indexes; bool omit_empty_base_classes = true; + + if (!GetCompilerType().IsValid()) + return ValueObjectSP(); + const size_t num_child_indexes = GetCompilerType().GetIndexOfChildMemberWithName( name.GetCString(), omit_empty_base_classes, child_indexes); @@ -1037,23 +1102,6 @@ ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error, return {total_bytes_read, was_capped}; } -std::pair<TypeValidatorResult, std::string> ValueObject::GetValidationStatus() { - if (!UpdateValueIfNeeded(true)) - return {TypeValidatorResult::Success, - ""}; // not the validator's job to discuss update problems - - if (m_validation_result.hasValue()) - return m_validation_result.getValue(); - - if (!m_type_validator_sp) - return {TypeValidatorResult::Success, ""}; // no validator no failure - - auto outcome = m_type_validator_sp->FormatObject(this); - - return (m_validation_result = {outcome.m_result, outcome.m_message}) - .getValue(); -} - const char *ValueObject::GetObjectDescription() { if (!UpdateValueIfNeeded(true)) return nullptr; @@ -1970,15 +2018,14 @@ bool ValueObject::GetBaseClassPath(Stream &s) { bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath(s); CompilerType compiler_type = GetCompilerType(); - std::string cxx_class_name; - bool this_had_base_class = - ClangASTContext::GetCXXClassName(compiler_type, cxx_class_name); - if (this_had_base_class) { + llvm::Optional<std::string> cxx_class_name = + ClangASTContext::GetCXXClassName(compiler_type); + if (cxx_class_name) { if (parent_had_base_class) s.PutCString("::"); - s.PutCString(cxx_class_name); + s.PutCString(cxx_class_name.getValue()); } - return parent_had_base_class || this_had_base_class; + return parent_had_base_class || cxx_class_name; } return false; } @@ -3063,10 +3110,6 @@ void ValueObject::ClearUserVisibleData(uint32_t clear_mask) { if (m_synthetic_value) m_synthetic_value = nullptr; } - - if ((clear_mask & eClearUserVisibleDataItemsValidator) == - eClearUserVisibleDataItemsValidator) - m_validation_result.reset(); } SymbolContextScope *ValueObject::GetSymbolContextScope() { |