summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/ValueObject.cpp
diff options
context:
space:
mode:
authorEnrico Granata <granata.enrico@gmail.com>2011-08-02 17:27:39 +0000
committerEnrico Granata <granata.enrico@gmail.com>2011-08-02 17:27:39 +0000
commitc3e320a7a0ccf754bd9e4ec0cac252845d5a24d2 (patch)
treeffc06a5a8545d9043ff96ee8cd576a84238d1cfe /lldb/source/Core/ValueObject.cpp
parent9ab728bb058429358fc1aba008e2d32c71106240 (diff)
downloadbcm5719-llvm-c3e320a7a0ccf754bd9e4ec0cac252845d5a24d2.tar.gz
bcm5719-llvm-c3e320a7a0ccf754bd9e4ec0cac252845d5a24d2.zip
Fixed a bug where a variable could not be formatted in a summary if its datatype already had a custom format
Fixed a bug where Objective-C variables coming out of the expression parser could crash the Python synthetic providers: - expression parser output has a "frozen data" component, which is a byte-exact copy of the value (in host memory), if trying to read into memory based on the host address, LLDB would crash. we are now passing the correct (target) pointer to the Python code Objective-C "id" variables are now formatted according to their dynamic type, if the -d option to frame variable is used: - Code based on the Objective-C 2.0 runtime is used to obtain this information without running code on the target llvm-svn: 136695
Diffstat (limited to 'lldb/source/Core/ValueObject.cpp')
-rw-r--r--lldb/source/Core/ValueObject.cpp107
1 files changed, 82 insertions, 25 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index fce3646c47e..77ee5c14e52 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -39,6 +39,7 @@
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
@@ -76,6 +77,7 @@ ValueObject::ValueObject (ValueObject &parent) :
m_deref_valobj(NULL),
m_format (eFormatDefault),
m_last_format_mgr_revision(0),
+ m_last_format_mgr_dynamic(lldb::eNoDynamicValues),
m_last_summary_format(),
m_forced_summary_format(),
m_last_value_format(),
@@ -91,6 +93,7 @@ ValueObject::ValueObject (ValueObject &parent) :
m_is_bitfield_for_scalar(false),
m_is_expression_path_child(false),
m_is_child_at_offset(false),
+ m_is_expression_result(false),
m_dump_printable_counter(0)
{
m_manager->ManageObject(this);
@@ -120,6 +123,7 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
m_deref_valobj(NULL),
m_format (eFormatDefault),
m_last_format_mgr_revision(0),
+ m_last_format_mgr_dynamic(lldb::eNoDynamicValues),
m_last_summary_format(),
m_forced_summary_format(),
m_last_value_format(),
@@ -135,6 +139,7 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
m_is_bitfield_for_scalar(false),
m_is_expression_path_child(false),
m_is_child_at_offset(false),
+ m_is_expression_result(false),
m_dump_printable_counter(0)
{
m_manager = new ValueObjectManager();
@@ -151,9 +156,15 @@ ValueObject::~ValueObject ()
bool
ValueObject::UpdateValueIfNeeded (bool update_format)
{
+ return UpdateValueIfNeeded(m_last_format_mgr_dynamic, update_format);
+}
+
+bool
+ValueObject::UpdateValueIfNeeded (lldb::DynamicValueType use_dynamic, bool update_format)
+{
if (update_format)
- UpdateFormatsIfNeeded();
+ UpdateFormatsIfNeeded(use_dynamic);
// If this is a constant value, then our success is predicated on whether
// we have an error or not
@@ -204,7 +215,7 @@ ValueObject::UpdateValueIfNeeded (bool update_format)
}
void
-ValueObject::UpdateFormatsIfNeeded()
+ValueObject::UpdateFormatsIfNeeded(lldb::DynamicValueType use_dynamic)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
if (log)
@@ -217,7 +228,8 @@ ValueObject::UpdateFormatsIfNeeded()
ClearCustomSummaryFormat();
m_summary_str.clear();
}
- if (m_last_format_mgr_revision != Debugger::Formatting::ValueFormats::GetCurrentRevision())
+ if ( (m_last_format_mgr_revision != Debugger::Formatting::ValueFormats::GetCurrentRevision()) ||
+ m_last_format_mgr_dynamic != use_dynamic)
{
if (m_last_summary_format.get())
m_last_summary_format.reset((StringSummaryFormat*)NULL);
@@ -228,11 +240,12 @@ ValueObject::UpdateFormatsIfNeeded()
m_synthetic_value = NULL;
- Debugger::Formatting::ValueFormats::Get(*this, m_last_value_format);
- Debugger::Formatting::GetSummaryFormat(*this, m_last_summary_format);
- Debugger::Formatting::GetSyntheticFilter(*this, m_last_synthetic_filter);
+ Debugger::Formatting::ValueFormats::Get(*this, use_dynamic, m_last_value_format);
+ Debugger::Formatting::GetSummaryFormat(*this, use_dynamic, m_last_summary_format);
+ Debugger::Formatting::GetSyntheticFilter(*this, use_dynamic, m_last_synthetic_filter);
m_last_format_mgr_revision = Debugger::Formatting::ValueFormats::GetCurrentRevision();
+ m_last_format_mgr_dynamic = use_dynamic;
ClearUserVisibleData();
}
@@ -241,14 +254,14 @@ ValueObject::UpdateFormatsIfNeeded()
DataExtractor &
ValueObject::GetDataExtractor ()
{
- UpdateValueIfNeeded();
+ UpdateValueIfNeeded(false);
return m_data;
}
const Error &
ValueObject::GetError()
{
- UpdateValueIfNeeded();
+ UpdateValueIfNeeded(false);
return m_error;
}
@@ -261,7 +274,7 @@ ValueObject::GetName() const
const char *
ValueObject::GetLocationAsCString ()
{
- if (UpdateValueIfNeeded())
+ if (UpdateValueIfNeeded(false))
{
if (m_location_str.empty())
{
@@ -358,7 +371,7 @@ ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
ValueObjectSP child_sp;
// We may need to update our value if we are dynamic
if (IsPossibleDynamicType ())
- UpdateValueIfNeeded();
+ UpdateValueIfNeeded(false);
if (idx < GetNumChildren())
{
// Check if we have already made the child value object?
@@ -395,7 +408,7 @@ ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
// We may need to update our value if we are dynamic
if (IsPossibleDynamicType ())
- UpdateValueIfNeeded();
+ UpdateValueIfNeeded(false);
std::vector<uint32_t> child_indexes;
clang::ASTContext *clang_ast = GetClangAST();
@@ -519,7 +532,7 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3
const char *
ValueObject::GetSummaryAsCString ()
{
- if (UpdateValueIfNeeded ())
+ if (UpdateValueIfNeeded (m_last_format_mgr_dynamic, true))
{
if (m_summary_str.empty())
{
@@ -775,7 +788,7 @@ const char *
ValueObject::GetObjectDescription ()
{
- if (!UpdateValueIfNeeded ())
+ if (!UpdateValueIfNeeded (m_last_format_mgr_dynamic, true))
return NULL;
if (!m_object_desc_str.empty())
@@ -826,7 +839,7 @@ ValueObject::GetValueAsCString ()
// If our byte size is zero this is an aggregate type that has children
if (ClangASTContext::IsAggregateType (GetClangType()) == false)
{
- if (UpdateValueIfNeeded())
+ if (UpdateValueIfNeeded(true))
{
if (m_value_str.empty())
{
@@ -841,7 +854,7 @@ ValueObject::GetValueAsCString ()
clang_type_t clang_type = GetClangType ();
if (clang_type)
{
- if (m_last_value_format)
+ if (m_format == lldb::eFormatDefault && m_last_value_format)
{
m_value_str = m_last_value_format->FormatObject(GetSP());
}
@@ -905,6 +918,24 @@ ValueObject::GetValueAsCString ()
return m_value_str.c_str();
}
+// if > 8bytes, 0 is returned. this method should mostly be used
+// to read address values out of pointers
+unsigned long long
+ValueObject::GetValueAsUnsigned()
+{
+ // If our byte size is zero this is an aggregate type that has children
+ if (ClangASTContext::IsAggregateType (GetClangType()) == false)
+ {
+ if (UpdateValueIfNeeded(true))
+ {
+ uint32_t offset = 0;
+ return m_data.GetMaxU64(&offset,
+ m_data.GetByteSize());
+ }
+ }
+ return 0;
+}
+
// this call should only return pointers to data that needs no special memory management
// (either because they are hardcoded strings, or because they are backed by some other
// object); returning any new()-ed or malloc()-ed data here, will lead to leaks!
@@ -1092,7 +1123,7 @@ ValueObject::DumpPrintableRepresentation(Stream& s,
addr_t
ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
{
- if (!UpdateValueIfNeeded())
+ if (!UpdateValueIfNeeded(false))
return LLDB_INVALID_ADDRESS;
switch (m_value.GetValueType())
@@ -1124,7 +1155,7 @@ ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_add
lldb::addr_t address = LLDB_INVALID_ADDRESS;
address_type = eAddressTypeInvalid;
- if (!UpdateValueIfNeeded())
+ if (!UpdateValueIfNeeded(false))
return address;
switch (m_value.GetValueType())
@@ -1161,7 +1192,7 @@ ValueObject::SetValueFromCString (const char *value_str)
{
// Make sure our value is up to date first so that our location and location
// type is valid.
- if (!UpdateValueIfNeeded())
+ if (!UpdateValueIfNeeded(false))
return false;
uint32_t count = 0;
@@ -1256,7 +1287,8 @@ ValueObject::Write ()
lldb::LanguageType
ValueObject::GetObjectRuntimeLanguage ()
{
- return ClangASTType::GetMinimumLanguage (GetClangType());
+ return ClangASTType::GetMinimumLanguage (GetClangAST(),
+ GetClangType());
}
void
@@ -1521,7 +1553,7 @@ ValueObject::CalculateSyntheticValue (lldb::SyntheticValueType use_synthetic)
if (use_synthetic == lldb::eNoSyntheticFilter)
return;
- UpdateFormatsIfNeeded();
+ UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
if (m_last_synthetic_filter.get() == NULL)
return;
@@ -1601,7 +1633,7 @@ ValueObject::GetSyntheticValue (SyntheticValueType use_synthetic)
if (use_synthetic == lldb::eNoSyntheticFilter)
return GetSP();
- UpdateFormatsIfNeeded();
+ UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
if (m_last_synthetic_filter.get() == NULL)
return GetSP();
@@ -2537,7 +2569,7 @@ ValueObject::DumpValueObject
{
if (valobj)
{
- bool update_success = valobj->UpdateValueIfNeeded ();
+ bool update_success = valobj->UpdateValueIfNeeded (use_dynamic, true);
if (update_success && use_dynamic != lldb::eNoDynamicValues)
{
@@ -2566,7 +2598,33 @@ ValueObject::DumpValueObject
// Always show the type for the top level items.
if (show_types || (curr_depth == 0 && !flat_output))
- s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
+ {
+ s.Printf("(%s", valobj->GetTypeName().AsCString("<invalid type>"));
+ if (use_dynamic != lldb::eNoDynamicValues &&
+ strcmp(valobj->GetTypeName().AsCString("NULL"), "id") == 0)
+ {
+ Process* process = valobj->GetUpdatePoint().GetProcessSP().get();
+ if (process == NULL)
+ s.Printf(") ");
+ else
+ {
+ ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
+ if (runtime == NULL)
+ s.Printf(") ");
+ else
+ {
+ ObjCLanguageRuntime::ObjCISA isa = runtime->GetISA(*valobj);
+ if (!runtime->IsValidISA(isa))
+ s.Printf(") ");
+ else
+ s.Printf(", dynamic type: %s) ",
+ runtime->GetActualTypeName(isa).GetCString());
+ }
+ }
+ }
+ else
+ s.Printf(") ");
+ }
if (flat_output)
@@ -2758,7 +2816,7 @@ ValueObject::CreateConstantValue (const ConstString &name)
{
ValueObjectSP valobj_sp;
- if (UpdateValueIfNeeded() && m_error.Success())
+ if (UpdateValueIfNeeded(false) && m_error.Success())
{
ExecutionContextScope *exe_scope = GetExecutionContextScope();
if (exe_scope)
@@ -2957,7 +3015,6 @@ ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
return valobj_sp;
}
-
ValueObject::EvaluationPoint::EvaluationPoint () :
m_thread_id (LLDB_INVALID_UID),
m_stop_id (0)
OpenPOWER on IntegriCloud