diff options
| author | Sean Callanan <scallanan@apple.com> | 2014-12-09 21:18:59 +0000 |
|---|---|---|
| committer | Sean Callanan <scallanan@apple.com> | 2014-12-09 21:18:59 +0000 |
| commit | 7375f3e30e3e8ecd3d03febeff780936677b7e18 (patch) | |
| tree | 602cf68f6c351fe9d10583f99e93ee2e58c3db53 | |
| parent | 21909e35cb06b7c0e2181254299817fdecbcad62 (diff) | |
| download | bcm5719-llvm-7375f3e30e3e8ecd3d03febeff780936677b7e18.tar.gz bcm5719-llvm-7375f3e30e3e8ecd3d03febeff780936677b7e18.zip | |
Fixed ValueObject::UpdateValueIfNeeded to keep
track of the checksum of the object so we can
track if it is modified. This fixes a testcase
(test/expression_command/issue_11588) on OS X.
Patch by Enrico Granata.
llvm-svn: 223830
| -rw-r--r-- | lldb/include/lldb/Core/DataExtractor.h | 9 | ||||
| -rw-r--r-- | lldb/include/lldb/Core/ValueObject.h | 16 | ||||
| -rw-r--r-- | lldb/source/Core/DataExtractor.cpp | 26 | ||||
| -rw-r--r-- | lldb/source/Core/ValueObject.cpp | 57 |
4 files changed, 89 insertions, 19 deletions
diff --git a/lldb/include/lldb/Core/DataExtractor.h b/lldb/include/lldb/Core/DataExtractor.h index e18397b6264..516953b00c3 100644 --- a/lldb/include/lldb/Core/DataExtractor.h +++ b/lldb/include/lldb/Core/DataExtractor.h @@ -13,9 +13,13 @@ #include "lldb/lldb-private.h" + +#include "llvm/ADT/SmallVector.h" + #include <limits.h> #include <stdint.h> #include <string.h> +#include <vector> namespace lldb_private { @@ -1309,6 +1313,11 @@ public: return size - offset; return 0; } + + void + Checksum (llvm::SmallVectorImpl<uint8_t> &dest, + uint64_t max_data = 0); + protected: diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index b95552526fa..47cd57a74d3 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -14,9 +14,11 @@ // C++ Includes #include <map> #include <vector> + // Other libraries and framework includes -// Project includes +#include "llvm/ADT/SmallVector.h" +// Project includes #include "lldb/lldb-private.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Error.h" @@ -270,12 +272,6 @@ public: m_mod_id = new_id; } - bool - IsFirstEvaluation () const - { - return m_first_update; - } - void SetNeedsUpdate () { @@ -324,7 +320,6 @@ public: ProcessModID m_mod_id; // This is the stop id when this ValueObject was last evaluated. ExecutionContextRef m_exe_ctx_ref; bool m_needs_update; - bool m_first_update; }; const EvaluationPoint & @@ -1103,6 +1098,8 @@ protected: ProcessModID m_user_id_of_forced_summary; AddressType m_address_type_of_ptr_or_ref_children; + llvm::SmallVector<uint8_t, 16> m_value_checksum; + bool m_value_is_valid:1, m_value_did_change:1, m_children_count_valid:1, @@ -1208,6 +1205,9 @@ protected: GetLocationAsCStringImpl (const Value& value, const DataExtractor& data); + bool + IsChecksumEmpty (); + private: //------------------------------------------------------------------ // For ValueObject only diff --git a/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp index 27dccfe5cf2..6e1d63095cf 100644 --- a/lldb/source/Core/DataExtractor.cpp +++ b/lldb/source/Core/DataExtractor.cpp @@ -22,7 +22,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/MathExtras.h" - +#include "llvm/Support/MD5.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" @@ -2238,3 +2238,27 @@ DataExtractor::Append(void* buf, offset_t length) return true; } + +void +DataExtractor::Checksum (llvm::SmallVectorImpl<uint8_t> &dest, + uint64_t max_data) +{ + if (max_data == 0) + max_data = GetByteSize(); + else + max_data = std::min(max_data, GetByteSize()); + + llvm::MD5 md5; + + const llvm::ArrayRef<uint8_t> data(GetDataStart(),max_data); + md5.update(data); + + llvm::MD5::MD5Result result; + md5.final(result); + + dest.resize(16); + std::copy(result, + result+16, + dest.begin()); +} + diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 624c06d5a75..5487b601655 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -98,6 +98,7 @@ ValueObject::ValueObject (ValueObject &parent) : m_type_validator_sp(), m_user_id_of_forced_summary(), m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid), + m_value_checksum(), m_value_is_valid (false), m_value_did_change (false), m_children_count_valid (false), @@ -147,6 +148,7 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope, m_type_validator_sp(), m_user_id_of_forced_summary(), m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type), + m_value_checksum(), m_value_is_valid (false), m_value_did_change (false), m_children_count_valid (false), @@ -192,7 +194,7 @@ ValueObject::UpdateValueIfNeeded (bool update_format) return m_error.Success(); } - bool first_update = m_update_point.IsFirstEvaluation(); + bool first_update = IsChecksumEmpty(); if (m_update_point.NeedsUpdating()) { @@ -221,10 +223,35 @@ ValueObject::UpdateValueIfNeeded (bool update_format) m_error.Clear(); // Call the pure virtual function to update the value + + bool need_compare_checksums = false; + llvm::SmallVector<uint8_t, 16> old_checksum; + + if (!first_update && CanProvideValue()) + { + need_compare_checksums = true; + old_checksum.resize(m_value_checksum.size()); + std::copy(m_value_checksum.begin(), m_value_checksum.end(), old_checksum.begin()); + } + bool success = UpdateValue (); SetValueIsValid (success); + if (success) + { + const uint64_t max_checksum_size = 128; + m_data.Checksum(m_value_checksum, + max_checksum_size); + } + else + { + need_compare_checksums = false; + m_value_checksum.clear(); + } + + assert (old_checksum.empty() == !need_compare_checksums); + if (first_update) SetValueDidChange (false); else if (!m_value_did_change && success == false) @@ -233,6 +260,11 @@ ValueObject::UpdateValueIfNeeded (bool update_format) // as changed if the value used to be valid and now isn't SetValueDidChange (value_was_valid); } + else if (need_compare_checksums) + { + SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0], m_value_checksum.size())); + } + } else { @@ -498,7 +530,6 @@ ValueObject::SetValueIsValid (bool b) bool ValueObject::GetValueDidChange () { - GetValueAsCString (); return m_value_did_change; } @@ -3834,16 +3865,14 @@ ValueObject::CastPointerType (const char *name, TypeSP &type_sp) ValueObject::EvaluationPoint::EvaluationPoint () : m_mod_id(), m_exe_ctx_ref(), - m_needs_update (true), - m_first_update (true) + m_needs_update (true) { } ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected): m_mod_id(), m_exe_ctx_ref(), - m_needs_update (true), - m_first_update (true) + m_needs_update (true) { ExecutionContext exe_ctx(exe_scope); TargetSP target_sp (exe_ctx.GetTargetSP()); @@ -3887,8 +3916,7 @@ ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref), - m_needs_update (true), - m_first_update (true) + m_needs_update (true) { } @@ -3982,7 +4010,6 @@ ValueObject::EvaluationPoint::SetUpdated () ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP()); if (process_sp) m_mod_id = process_sp->GetModID(); - m_first_update = false; m_needs_update = false; } @@ -4183,7 +4210,17 @@ ValueObject::GetPreferredDisplayLanguage () bool ValueObject::CanProvideValue () { - return (false == GetClangType().IsAggregateType()); + // we need to support invalid types as providers of values because some bare-board + // debugging scenarios have no notion of types, but still manage to have raw numeric + // values for things like registers. sigh. + const ClangASTType &type(GetClangType()); + return (false == type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue)); +} + +bool +ValueObject::IsChecksumEmpty () +{ + return m_value_checksum.empty(); } ValueObjectSP |

