summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core
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
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')
-rw-r--r--lldb/source/Core/Debugger.cpp23
-rw-r--r--lldb/source/Core/FormatClasses.cpp45
-rw-r--r--lldb/source/Core/ValueObject.cpp107
-rw-r--r--lldb/source/Core/ValueObjectChild.cpp2
-rw-r--r--lldb/source/Core/ValueObjectDynamicValue.cpp8
5 files changed, 149 insertions, 36 deletions
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index a217ddb36ec..9442600a4d7 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -1010,22 +1010,35 @@ Debugger::FormatPrompt
if (!vobj)
break;
+ if (log)
+ log->Printf("initial string: %s",var_name_begin);
+
// check for *var and *svar
if (*var_name_begin == '*')
{
do_deref_pointer = true;
var_name_begin++;
}
+
+ if (log)
+ log->Printf("initial string: %s",var_name_begin);
+
if (*var_name_begin == 's')
{
vobj = vobj->GetSyntheticValue(lldb::eUseSyntheticFilter).get();
var_name_begin++;
}
+ if (log)
+ log->Printf("initial string: %s",var_name_begin);
+
// should be a 'v' by now
if (*var_name_begin != 'v')
break;
+ if (log)
+ log->Printf("initial string: %s",var_name_begin);
+
ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
ValueObject::eDereference : ValueObject::eNothing);
ValueObject::GetValueForExpressionPathOptions options;
@@ -1765,9 +1778,9 @@ Debugger::Formatting::ForceUpdate()
}
bool
-Debugger::Formatting::ValueFormats::Get(ValueObject& vobj, ValueFormat::SharedPointer &entry)
+Debugger::Formatting::ValueFormats::Get(ValueObject& vobj, lldb::DynamicValueType use_dynamic, ValueFormat::SharedPointer &entry)
{
- return GetFormatManager().Value().Get(vobj,entry);
+ return GetFormatManager().Value().Get(vobj,entry, use_dynamic);
}
void
@@ -1808,15 +1821,17 @@ Debugger::Formatting::ValueFormats::GetCount()
bool
Debugger::Formatting::GetSummaryFormat(ValueObject& vobj,
+ lldb::DynamicValueType use_dynamic,
lldb::SummaryFormatSP& entry)
{
- return GetFormatManager().Get(vobj, entry);
+ return GetFormatManager().Get(vobj, entry, use_dynamic);
}
bool
Debugger::Formatting::GetSyntheticFilter(ValueObject& vobj,
+ lldb::DynamicValueType use_dynamic,
lldb::SyntheticChildrenSP& entry)
{
- return GetFormatManager().Get(vobj, entry);
+ return GetFormatManager().Get(vobj, entry, use_dynamic);
}
bool
diff --git a/lldb/source/Core/FormatClasses.cpp b/lldb/source/Core/FormatClasses.cpp
index 046cc705d00..48097087253 100644
--- a/lldb/source/Core/FormatClasses.cpp
+++ b/lldb/source/Core/FormatClasses.cpp
@@ -21,6 +21,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FormatClasses.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Target/StackFrame.h"
@@ -121,8 +122,29 @@ StringSummaryFormat::GetDescription()
std::string
ScriptSummaryFormat::FormatObject(lldb::ValueObjectSP object)
{
+ lldb::ValueObjectSP target_object;
+ if (object->GetIsExpressionResult() &&
+ ClangASTContext::IsPointerType(object->GetClangType()) &&
+ object->GetValue().GetValueType() == Value::eValueTypeHostAddress)
+ {
+ // when using the expression parser, an additional layer of "frozen data"
+ // can be created, which is basically a byte-exact copy of the data returned
+ // by the expression, but in host memory. because Python code might need to read
+ // into the object memory in non-obvious ways, we need to hand it the target version
+ // of the expression output
+ lldb::addr_t tgt_address = object->GetValueAsUnsigned();
+ target_object = ValueObjectConstResult::Create (object->GetExecutionContextScope(),
+ object->GetClangAST(),
+ object->GetClangType(),
+ object->GetName(),
+ tgt_address,
+ eAddressTypeLoad,
+ object->GetUpdatePoint().GetProcessSP()->GetAddressByteSize());
+ }
+ else
+ target_object = object;
return std::string(ScriptInterpreterPython::CallPythonScriptFunction(m_function_name.c_str(),
- object).c_str());
+ target_object).c_str());
}
std::string
@@ -171,7 +193,26 @@ m_python_class(pclass)
return;
}
- m_interpreter = be->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+ if (be->GetIsExpressionResult() &&
+ ClangASTContext::IsPointerType(be->GetClangType()) &&
+ be->GetValue().GetValueType() == Value::eValueTypeHostAddress)
+ {
+ // when using the expression parser, an additional layer of "frozen data"
+ // can be created, which is basically a byte-exact copy of the data returned
+ // by the expression, but in host memory. because Python code might need to read
+ // into the object memory in non-obvious ways, we need to hand it the target version
+ // of the expression output
+ lldb::addr_t tgt_address = be->GetValueAsUnsigned();
+ m_backend = ValueObjectConstResult::Create (be->GetExecutionContextScope(),
+ be->GetClangAST(),
+ be->GetClangType(),
+ be->GetName(),
+ tgt_address,
+ eAddressTypeLoad,
+ be->GetUpdatePoint().GetProcessSP()->GetAddressByteSize());
+ }
+
+ m_interpreter = m_backend->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
if (m_interpreter == NULL)
m_wrapper = NULL;
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)
diff --git a/lldb/source/Core/ValueObjectChild.cpp b/lldb/source/Core/ValueObjectChild.cpp
index 8ddf195b51f..2ded7b50e82 100644
--- a/lldb/source/Core/ValueObjectChild.cpp
+++ b/lldb/source/Core/ValueObjectChild.cpp
@@ -97,7 +97,7 @@ ValueObjectChild::UpdateValue ()
ValueObject* parent = m_parent;
if (parent)
{
- if (parent->UpdateValueIfNeeded())
+ if (parent->UpdateValueIfNeeded(false))
{
m_value.SetContext(Value::eContextTypeClangType, m_clang_type);
diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp
index 885e68fd3bd..beecaa95238 100644
--- a/lldb/source/Core/ValueObjectDynamicValue.cpp
+++ b/lldb/source/Core/ValueObjectDynamicValue.cpp
@@ -60,7 +60,7 @@ ValueObjectDynamicValue::GetClangType ()
ConstString
ValueObjectDynamicValue::GetTypeName()
{
- const bool success = UpdateValueIfNeeded();
+ const bool success = UpdateValueIfNeeded(false);
if (success && m_type_sp)
return ClangASTType::GetConstTypeName (GetClangType());
else
@@ -70,7 +70,7 @@ ValueObjectDynamicValue::GetTypeName()
uint32_t
ValueObjectDynamicValue::CalculateNumChildren()
{
- const bool success = UpdateValueIfNeeded();
+ const bool success = UpdateValueIfNeeded(false);
if (success && m_type_sp)
return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
else
@@ -90,7 +90,7 @@ ValueObjectDynamicValue::GetClangAST ()
size_t
ValueObjectDynamicValue::GetByteSize()
{
- const bool success = UpdateValueIfNeeded();
+ const bool success = UpdateValueIfNeeded(false);
if (success && m_type_sp)
return m_value.GetValueByteSize(GetClangAST(), NULL);
else
@@ -109,7 +109,7 @@ ValueObjectDynamicValue::UpdateValue ()
SetValueIsValid (false);
m_error.Clear();
- if (!m_parent->UpdateValueIfNeeded())
+ if (!m_parent->UpdateValueIfNeeded(false))
{
// The dynamic value failed to get an error, pass the error along
if (m_error.Success() && m_parent->GetError().Fail())
OpenPOWER on IntegriCloud