mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-11 02:16:50 +00:00
some editing of data visualization error messages to make them more meaningful
debugging printfs() for data visualization turned into a meaningful log: - introduced a new log category `types' in channel `lldb' llvm-svn: 135773
This commit is contained in:
parent
4535b9194a
commit
e992a0899e
@ -46,6 +46,7 @@ namespace std
|
||||
#include "lldb/Core/FormatClasses.h"
|
||||
#include "lldb/Core/InputReaderStack.h"
|
||||
#include "lldb/Core/Listener.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/RegularExpression.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/SourceManager.h"
|
||||
@ -58,6 +59,8 @@ namespace std
|
||||
#include "lldb/Target/StackFrame.h"
|
||||
#include "lldb/Target/TargetList.h"
|
||||
|
||||
using lldb::LogSP;
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class IFormatChangeListener
|
||||
@ -269,13 +272,22 @@ private:
|
||||
MapValueType& entry,
|
||||
uint32_t& reason)
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
|
||||
if (type.isNull())
|
||||
{
|
||||
if (log)
|
||||
log->Printf("type is NULL, returning");
|
||||
return false;
|
||||
}
|
||||
// clang::QualType type = q_type.getUnqualifiedType();
|
||||
type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict();
|
||||
const clang::Type* typePtr = type.getTypePtrOrNull();
|
||||
if (!typePtr)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("type is NULL, returning");
|
||||
return false;
|
||||
}
|
||||
ConstString name(ClangASTType::GetTypeNameForQualType(type).c_str());
|
||||
if (vobj.GetBitfieldBitSize() > 0)
|
||||
{
|
||||
@ -283,13 +295,24 @@ private:
|
||||
StreamString sstring;
|
||||
sstring.Printf("%s:%d",name.AsCString(),vobj.GetBitfieldBitSize());
|
||||
name = ConstString(sstring.GetData());
|
||||
if (log)
|
||||
log->Printf("appended bitfield info, final result is %s", name.GetCString());
|
||||
}
|
||||
//printf("trying to get format for VO name %s of type %s\n",vobj.GetName().AsCString(),name.AsCString());
|
||||
if (log)
|
||||
log->Printf("trying to get format for VO name %s of type %s",vobj.GetName().AsCString(),name.AsCString());
|
||||
if (Get(name.GetCString(), entry))
|
||||
{
|
||||
if (log)
|
||||
log->Printf("direct match found, returning");
|
||||
return true;
|
||||
}
|
||||
if (log)
|
||||
log->Printf("no direct match");
|
||||
// look for a "base type", whatever that means
|
||||
if (typePtr->isReferenceType())
|
||||
{
|
||||
if (log)
|
||||
log->Printf("stripping reference");
|
||||
if (Get(vobj,type.getNonReferenceType(),entry, reason) && !entry->m_skip_references)
|
||||
{
|
||||
reason |= lldb::eFormatterStrippedPointerReference;
|
||||
@ -298,6 +321,8 @@ private:
|
||||
}
|
||||
if (typePtr->isPointerType())
|
||||
{
|
||||
if (log)
|
||||
log->Printf("stripping pointer");
|
||||
if (Get(vobj, typePtr->getPointeeType(), entry, reason) && !entry->m_skip_pointers)
|
||||
{
|
||||
reason |= lldb::eFormatterStrippedPointerReference;
|
||||
@ -306,6 +331,8 @@ private:
|
||||
}
|
||||
if (typePtr->isObjCObjectPointerType())
|
||||
{
|
||||
if (log)
|
||||
log->Printf("stripping ObjC pointer");
|
||||
/*
|
||||
for some reason, C++ can quite easily obtain the type hierarchy for a ValueObject
|
||||
even if the VO represent a pointer-to-class, as long as the typePtr is right
|
||||
@ -325,19 +352,21 @@ private:
|
||||
const clang::ObjCObjectType *objc_class_type = typePtr->getAs<clang::ObjCObjectType>();
|
||||
if (objc_class_type)
|
||||
{
|
||||
//printf("working with ObjC\n");
|
||||
if (log)
|
||||
log->Printf("working with ObjC");
|
||||
clang::ASTContext *ast = vobj.GetClangAST();
|
||||
if (ClangASTContext::GetCompleteType(ast, vobj.GetClangType()) && !objc_class_type->isObjCId())
|
||||
{
|
||||
clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
|
||||
if (class_interface_decl)
|
||||
{
|
||||
//printf("down here\n");
|
||||
if (log)
|
||||
log->Printf("got an ObjCInterfaceDecl");
|
||||
clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
|
||||
//printf("one further step and we're there...\n");
|
||||
if (superclass_interface_decl)
|
||||
{
|
||||
//printf("the end is here\n");
|
||||
if (log)
|
||||
log->Printf("got a parent class for this ObjC class");
|
||||
clang::QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
|
||||
if (Get(vobj, ivar_qual_type, entry, reason) && entry->m_cascades)
|
||||
{
|
||||
@ -351,6 +380,8 @@ private:
|
||||
// for C++ classes, navigate up the hierarchy
|
||||
if (typePtr->isRecordType())
|
||||
{
|
||||
if (log)
|
||||
log->Printf("working with C++");
|
||||
clang::CXXRecordDecl* record = typePtr->getAsCXXRecordDecl();
|
||||
if (record)
|
||||
{
|
||||
@ -361,6 +392,8 @@ private:
|
||||
clang::CXXRecordDecl::base_class_iterator pos,end;
|
||||
if (record->getNumBases() > 0)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("look into bases");
|
||||
end = record->bases_end();
|
||||
for (pos = record->bases_begin(); pos != end; pos++)
|
||||
{
|
||||
@ -373,6 +406,8 @@ private:
|
||||
}
|
||||
if (record->getNumVBases() > 0)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("look into VBases");
|
||||
end = record->vbases_end();
|
||||
for (pos = record->vbases_begin(); pos != end; pos++)
|
||||
{
|
||||
@ -390,6 +425,8 @@ private:
|
||||
const clang::TypedefType* type_tdef = type->getAs<clang::TypedefType>();
|
||||
if (type_tdef)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("stripping typedef");
|
||||
if ((Get(vobj, type_tdef->getDecl()->getUnderlyingType(), entry, reason)) && entry->m_cascades)
|
||||
{
|
||||
reason |= lldb::eFormatterNavigatedTypedefs;
|
||||
|
@ -38,6 +38,7 @@
|
||||
#define LIBLLDB_LOG_API (1u << 16)
|
||||
#define LIBLLDB_LOG_SCRIPT (1u << 17)
|
||||
#define LIBLLDB_LOG_COMMANDS (1U << 18)
|
||||
#define LIBLLDB_LOG_TYPES (1u << 19)
|
||||
#define LIBLLDB_LOG_ALL (UINT32_MAX)
|
||||
#define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\
|
||||
LIBLLDB_LOG_THREAD |\
|
||||
|
@ -694,18 +694,12 @@ TestPromptFormats (StackFrame *frame)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME this should eventually be replaced by proper use of LLDB logging facilities
|
||||
//#define VERBOSE_FORMATPROMPT_OUTPUT
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
#define IFERROR_PRINT_IT if (error.Fail()) \
|
||||
{ \
|
||||
printf("ERROR: %s\n",error.AsCString("unknown")); \
|
||||
if (log) \
|
||||
log->Printf("ERROR: %s\n", error.AsCString("unknown")); \
|
||||
break; \
|
||||
}
|
||||
#else // IFERROR_PRINT_IT
|
||||
#define IFERROR_PRINT_IT if (error.Fail()) \
|
||||
break;
|
||||
#endif // IFERROR_PRINT_IT
|
||||
|
||||
static bool
|
||||
ScanFormatDescriptor(const char* var_name_begin,
|
||||
@ -715,36 +709,55 @@ ScanFormatDescriptor(const char* var_name_begin,
|
||||
lldb::Format* custom_format,
|
||||
ValueObject::ValueObjectRepresentationStyle* val_obj_display)
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
|
||||
*percent_position = ::strchr(var_name_begin,'%');
|
||||
if (!*percent_position || *percent_position > var_name_end)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("no format descriptor in string, skipping");
|
||||
*var_name_final = var_name_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
*var_name_final = *percent_position;
|
||||
char* format_name = new char[var_name_end-*var_name_final]; format_name[var_name_end-*var_name_final-1] = '\0';
|
||||
memcpy(format_name, *var_name_final+1, var_name_end-*var_name_final-1);
|
||||
if (log)
|
||||
log->Printf("parsing %s as a format descriptor", format_name);
|
||||
if ( !FormatManager::GetFormatFromCString(format_name,
|
||||
true,
|
||||
*custom_format) )
|
||||
{
|
||||
if (log)
|
||||
log->Printf("%s is an unknown format", format_name);
|
||||
// if this is an @ sign, print ObjC description
|
||||
if (*format_name == '@')
|
||||
*val_obj_display = ValueObject::eDisplayLanguageSpecific;
|
||||
// if this is a V, print the value using the default format
|
||||
if (*format_name == 'V')
|
||||
else if (*format_name == 'V')
|
||||
*val_obj_display = ValueObject::eDisplayValue;
|
||||
// if this is an L, print the location of the value
|
||||
if (*format_name == 'L')
|
||||
else if (*format_name == 'L')
|
||||
*val_obj_display = ValueObject::eDisplayLocation;
|
||||
// if this is an S, print the summary after all
|
||||
if (*format_name == 'S')
|
||||
else if (*format_name == 'S')
|
||||
*val_obj_display = ValueObject::eDisplaySummary;
|
||||
else if (log)
|
||||
log->Printf("%s is an error, leaving the previous value alone", format_name);
|
||||
}
|
||||
// a good custom format tells us to print the value using it
|
||||
else
|
||||
{
|
||||
if (log)
|
||||
log->Printf("will display value for this VO");
|
||||
*val_obj_display = ValueObject::eDisplayValue;
|
||||
}
|
||||
delete format_name;
|
||||
}
|
||||
if (log)
|
||||
log->Printf("final format description outcome: custom_format = %d, val_obj_display = %d",
|
||||
*custom_format,
|
||||
*val_obj_display);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -759,6 +772,7 @@ ScanBracketedRange(const char* var_name_begin,
|
||||
int64_t* index_lower,
|
||||
int64_t* index_higher)
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
|
||||
*open_bracket_position = ::strchr(var_name_begin,'[');
|
||||
if (*open_bracket_position && *open_bracket_position < var_name_final)
|
||||
{
|
||||
@ -769,6 +783,8 @@ ScanBracketedRange(const char* var_name_begin,
|
||||
*var_name_final_if_array_range = *open_bracket_position;
|
||||
if (*close_bracket_position - *open_bracket_position == 1)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("[] detected.. going from 0 to end of data");
|
||||
*index_lower = 0;
|
||||
}
|
||||
else if (*separator_position == NULL || *separator_position > var_name_end)
|
||||
@ -776,24 +792,34 @@ ScanBracketedRange(const char* var_name_begin,
|
||||
char *end = NULL;
|
||||
*index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
|
||||
*index_higher = *index_lower;
|
||||
//printf("got to read low=%d high same\n",bitfield_lower);
|
||||
if (log)
|
||||
log->Printf("[%d] detected, high index is same",index_lower);
|
||||
}
|
||||
else if (*close_bracket_position && *close_bracket_position < var_name_end)
|
||||
{
|
||||
char *end = NULL;
|
||||
*index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
|
||||
*index_higher = ::strtoul (*separator_position+1, &end, 0);
|
||||
//printf("got to read low=%d high=%d\n",bitfield_lower,bitfield_higher);
|
||||
if (log)
|
||||
log->Printf("[%d-%d] detected",index_lower,index_higher);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (log)
|
||||
log->Printf("expression is erroneous, cannot extract indices out of it");
|
||||
return false;
|
||||
}
|
||||
if (*index_lower > *index_higher && *index_higher > 0)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("swapping indices");
|
||||
int temp = *index_lower;
|
||||
*index_lower = *index_higher;
|
||||
*index_higher = temp;
|
||||
}
|
||||
}
|
||||
else if (log)
|
||||
log->Printf("no bracketed range, skipping entirely");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -806,26 +832,30 @@ ExpandExpressionPath(ValueObject* vobj,
|
||||
const char* var_name_final,
|
||||
Error& error)
|
||||
{
|
||||
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
|
||||
StreamString sstring;
|
||||
VariableSP var_sp;
|
||||
|
||||
if (*do_deref_pointer)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("been told to deref_pointer by caller");
|
||||
sstring.PutChar('*');
|
||||
}
|
||||
else if (vobj->IsDereferenceOfParent() && ClangASTContext::IsPointerType(vobj->GetParent()->GetClangType()) && !vobj->IsArrayItemForPointer())
|
||||
{
|
||||
if (log)
|
||||
log->Printf("decided to deref_pointer myself");
|
||||
sstring.PutChar('*');
|
||||
*do_deref_pointer = true;
|
||||
}
|
||||
|
||||
vobj->GetExpressionPath(sstring, true, ValueObject::eHonorPointers);
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
printf("name to expand in phase 0: %s\n",sstring.GetData());
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
if (log)
|
||||
log->Printf("expression path to expand in phase 0: %s",sstring.GetData());
|
||||
sstring.PutRawBytes(var_name_begin+3, var_name_final-var_name_begin-3);
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
printf("name to expand in phase 1: %s\n",sstring.GetData());
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
if (log)
|
||||
log->Printf("expression path to expand in phase 1: %s",sstring.GetData());
|
||||
std::string name = std::string(sstring.GetData());
|
||||
ValueObjectSP target = frame->GetValueForVariableExpressionPath (name.c_str(),
|
||||
eNoDynamicValues,
|
||||
@ -841,12 +871,12 @@ ExpandIndexedExpression(ValueObject* vobj,
|
||||
StackFrame* frame,
|
||||
bool deref_pointer)
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
|
||||
const char* ptr_deref_format = "[%d]";
|
||||
std::auto_ptr<char> ptr_deref_buffer(new char[10]);
|
||||
::sprintf(ptr_deref_buffer.get(), ptr_deref_format, index);
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
printf("name to deref: %s\n",ptr_deref_buffer.get());
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
if (log)
|
||||
log->Printf("name to deref: %s",ptr_deref_buffer.get());
|
||||
const char* first_unparsed;
|
||||
ValueObject::GetValueForExpressionPathOptions options;
|
||||
ValueObject::ExpressionPathEndResultType final_value_type;
|
||||
@ -860,20 +890,18 @@ ExpandIndexedExpression(ValueObject* vobj,
|
||||
&what_next);
|
||||
if (!item)
|
||||
{
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
printf("ERROR: unparsed portion = %s, why stopping = %d,"
|
||||
" final_value_type %d\n",
|
||||
if (log)
|
||||
log->Printf("ERROR: unparsed portion = %s, why stopping = %d,"
|
||||
" final_value_type %d",
|
||||
first_unparsed, reason_to_stop, final_value_type);
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
}
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
else
|
||||
{
|
||||
printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
|
||||
" final_value_type %d\n",
|
||||
if (log)
|
||||
log->Printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
|
||||
" final_value_type %d",
|
||||
first_unparsed, reason_to_stop, final_value_type);
|
||||
}
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -892,6 +920,7 @@ Debugger::FormatPrompt
|
||||
ValueObject* realvobj = NULL; // makes it super-easy to parse pointers
|
||||
bool success = true;
|
||||
const char *p;
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
|
||||
for (p = format; *p != '\0'; ++p)
|
||||
{
|
||||
if (realvobj)
|
||||
@ -967,8 +996,8 @@ Debugger::FormatPrompt
|
||||
const RegisterInfo *reg_info = NULL;
|
||||
RegisterContext *reg_ctx = NULL;
|
||||
bool do_deref_pointer = false;
|
||||
ValueObject::ExpressionPathScanEndReason reason_to_stop;
|
||||
ValueObject::ExpressionPathEndResultType final_value_type;
|
||||
ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eEndOfString;
|
||||
ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::ePlain;
|
||||
|
||||
// Each variable must set success to true below...
|
||||
bool var_success = false;
|
||||
@ -1050,9 +1079,8 @@ Debugger::FormatPrompt
|
||||
::memset(expr_path.get(), 0, var_name_final-var_name_begin-1);
|
||||
memcpy(expr_path.get(), var_name_begin+3,var_name_final-var_name_begin-3);
|
||||
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
printf("symbol to expand: %s\n",expr_path.get());
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
if (log)
|
||||
log->Printf("symbol to expand: %s",expr_path.get());
|
||||
|
||||
target = vobj->GetValueForExpressionPath(expr_path.get(),
|
||||
&first_unparsed,
|
||||
@ -1063,21 +1091,19 @@ Debugger::FormatPrompt
|
||||
|
||||
if (!target)
|
||||
{
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
printf("ERROR: unparsed portion = %s, why stopping = %d,"
|
||||
" final_value_type %d\n",
|
||||
if (log)
|
||||
log->Printf("ERROR: unparsed portion = %s, why stopping = %d,"
|
||||
" final_value_type %d",
|
||||
first_unparsed, reason_to_stop, final_value_type);
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
break;
|
||||
}
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
else
|
||||
{
|
||||
printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
|
||||
" final_value_type %d\n",
|
||||
if (log)
|
||||
log->Printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
|
||||
" final_value_type %d",
|
||||
first_unparsed, reason_to_stop, final_value_type);
|
||||
}
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
}
|
||||
else
|
||||
break;
|
||||
@ -1103,26 +1129,31 @@ Debugger::FormatPrompt
|
||||
|
||||
if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eDisplayValue) // this should be wrong, but there are some exceptions
|
||||
{
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
printf("I am into array || pointer && !range\n");
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
if (log)
|
||||
log->Printf("I am into array || pointer && !range");
|
||||
// try to use the special cases
|
||||
var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
|
||||
if (!var_success)
|
||||
s << "<invalid, please use [] operator>";
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
printf("outcome was : %s\n", var_success ? "good" : "bad");
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
if (log)
|
||||
log->Printf("special cases did%s match", var_success ? "" : "n't");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_array_range)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("dumping ordinary printable output");
|
||||
var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if (log)
|
||||
log->Printf("checking if I can handle as array");
|
||||
if (!is_array && !is_pointer)
|
||||
break;
|
||||
|
||||
if (log)
|
||||
log->Printf("handle as array");
|
||||
const char* special_directions = NULL;
|
||||
StreamString special_directions_writer;
|
||||
if (close_bracket_position && (var_name_end-close_bracket_position > 1))
|
||||
@ -1151,16 +1182,14 @@ Debugger::FormatPrompt
|
||||
|
||||
if (!item)
|
||||
{
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
printf("ERROR\n");
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
if (log)
|
||||
log->Printf("ERROR in getting child item at index %d", index_lower);
|
||||
}
|
||||
#ifdef VERBOSE_FORMATPROMPT_OUTPUT
|
||||
else
|
||||
{
|
||||
printf("special_directions: %s\n",special_directions);
|
||||
if (log)
|
||||
log->Printf("special_directions for child item: %s",special_directions);
|
||||
}
|
||||
#endif //VERBOSE_FORMATPROMPT_OUTPUT
|
||||
|
||||
if (!special_directions)
|
||||
var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
|
||||
|
@ -885,6 +885,9 @@ ValueObject::GetValueAsCString ()
|
||||
return m_value_str.c_str();
|
||||
}
|
||||
|
||||
// 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!
|
||||
const char *
|
||||
ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
|
||||
lldb::Format custom_format)
|
||||
@ -921,10 +924,18 @@ ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_d
|
||||
if (val_obj_display == eDisplayValue)
|
||||
return_value = GetSummaryAsCString();
|
||||
else if (val_obj_display == eDisplaySummary)
|
||||
return_value = GetValueAsCString();
|
||||
{
|
||||
if (ClangASTContext::IsAggregateType (GetClangType()) == true)
|
||||
{
|
||||
// this thing has no value
|
||||
return_value = "<no summary defined for this datatype>";
|
||||
}
|
||||
else
|
||||
return_value = GetValueAsCString();
|
||||
}
|
||||
}
|
||||
|
||||
return (return_value ? return_value : "<error>");
|
||||
return (return_value ? return_value : "<no printable representation>");
|
||||
|
||||
}
|
||||
|
||||
@ -980,7 +991,7 @@ ValueObject::DumpPrintableRepresentation(Stream& s,
|
||||
ValueObjectSP child = GetChildAtIndex(low,true);
|
||||
if (!child.get())
|
||||
{
|
||||
s << "<error>";
|
||||
s << "<invalid child>";
|
||||
continue;
|
||||
}
|
||||
child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, custom_format);
|
||||
@ -1018,7 +1029,7 @@ ValueObject::DumpPrintableRepresentation(Stream& s,
|
||||
ValueObjectSP child = GetChildAtIndex(low,true);
|
||||
if (!child.get())
|
||||
{
|
||||
s << "<error>";
|
||||
s << "<invalid child>";
|
||||
continue;
|
||||
}
|
||||
child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, format);
|
||||
|
@ -134,6 +134,7 @@ lldb_private::DisableLog (Args &args, Stream *feedback_strm)
|
||||
else if (0 == ::strncasecmp(arg, "conn", 4)) flag_bits &= ~LIBLLDB_LOG_CONNECTION;
|
||||
else if (0 == ::strncasecmp(arg, "host", 4)) flag_bits &= ~LIBLLDB_LOG_HOST;
|
||||
else if (0 == ::strncasecmp(arg, "unwind", 6)) flag_bits &= ~LIBLLDB_LOG_UNWIND;
|
||||
else if (0 == ::strncasecmp(arg, "types", 5)) flag_bits &= ~LIBLLDB_LOG_TYPES;
|
||||
else
|
||||
{
|
||||
feedback_strm->Printf ("error: unrecognized log category '%s'\n", arg);
|
||||
@ -200,6 +201,7 @@ lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, Args &ar
|
||||
else if (0 == ::strncasecmp(arg, "conn", 4)) flag_bits |= LIBLLDB_LOG_CONNECTION;
|
||||
else if (0 == ::strncasecmp(arg, "host", 4)) flag_bits |= LIBLLDB_LOG_HOST;
|
||||
else if (0 == ::strncasecmp(arg, "unwind", 6)) flag_bits |= LIBLLDB_LOG_UNWIND;
|
||||
else if (0 == ::strncasecmp(arg, "types", 5)) flag_bits |= LIBLLDB_LOG_TYPES;
|
||||
else
|
||||
{
|
||||
feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
|
||||
@ -238,5 +240,6 @@ lldb_private::ListLogCategories (Stream *strm)
|
||||
"\tstep - log step related activities\n"
|
||||
"\tunwind - log stack unwind activities\n"
|
||||
"\tverbose - enable verbose logging\n"
|
||||
"\twatch - log watchpoint related activities\n");
|
||||
"\twatch - log watchpoint related activities\n"
|
||||
"\ttypes - log type system related activities\n");
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class DataFormatterTestCase(TestBase):
|
||||
self.runCmd("type summary add -f \"${var%V}\" SomeData")
|
||||
|
||||
self.expect("frame variable data",
|
||||
substrs = ['error'])
|
||||
substrs = ['no printable representation'])
|
||||
# ${var%s}
|
||||
self.runCmd("type summary add -f \"ptr = ${var%s}\" \"char *\"")
|
||||
|
||||
@ -198,12 +198,13 @@ class DataFormatterTestCase(TestBase):
|
||||
'{0x00000009},{0x00000008},{0x00000007},{0x00000006},{0x00000005}'])
|
||||
|
||||
# printing full array as an array
|
||||
self.runCmd("log enable lldb types -f dummy.log")
|
||||
self.runCmd("type summary add -f \"arr = ${var%uint32_t[]}\" \"int [5]\"")
|
||||
|
||||
self.expect("frame variable intarr",
|
||||
substrs = ['intarr = arr =',
|
||||
'0x00000001,0x00000001,0x00000002,0x00000003,0x00000005'])
|
||||
|
||||
self.runCmd("log disable lldb types")
|
||||
self.expect("frame variable other.intarr",
|
||||
substrs = ['intarr = arr =',
|
||||
'0x00000009,0x00000008,0x00000007,0x00000006,0x00000005'])
|
||||
|
Loading…
x
Reference in New Issue
Block a user