diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 4eb12819dd..ac597c6973 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -265,6 +265,7 @@ Application Debugger : ValueNodeContainer.cpp # value/type_handlers + BListTypeHandler.cpp BMessageTypeHandler.cpp CStringTypeHandler.cpp @@ -279,6 +280,7 @@ Application Debugger : # value/value_nodes AddressValueNode.cpp ArrayValueNode.cpp + BListValueNode.cpp BMessageValueNode.cpp CompoundValueNode.cpp CStringValueNode.cpp diff --git a/src/apps/debugger/value/TypeHandlerRoster.cpp b/src/apps/debugger/value/TypeHandlerRoster.cpp index eda2839ba7..985d03cb0d 100644 --- a/src/apps/debugger/value/TypeHandlerRoster.cpp +++ b/src/apps/debugger/value/TypeHandlerRoster.cpp @@ -14,6 +14,7 @@ #include "AddressValueNode.h" #include "ArrayValueNode.h" #include "CompoundValueNode.h" +#include "BListTypeHandler.h" #include "BMessageTypeHandler.h" #include "CStringTypeHandler.h" #include "EnumerationValueNode.h" @@ -152,6 +153,7 @@ TypeHandlerRoster::RegisterDefaultHandlers() REGISTER_SPECIALIZED_HANDLER(CString); REGISTER_SPECIALIZED_HANDLER(BMessage); + REGISTER_SPECIALIZED_HANDLER(BList); return B_OK; } diff --git a/src/apps/debugger/value/type_handlers/BListTypeHandler.cpp b/src/apps/debugger/value/type_handlers/BListTypeHandler.cpp new file mode 100644 index 0000000000..c5918ed287 --- /dev/null +++ b/src/apps/debugger/value/type_handlers/BListTypeHandler.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "BListTypeHandler.h" + +#include + +#include "BListValueNode.h" +#include "Type.h" + + +BListTypeHandler::~BListTypeHandler() +{ +} + + +float +BListTypeHandler::SupportsType(Type* type) +{ + if (dynamic_cast(type) != NULL + && type->Name() == "BList") + return 1.0f; + + return 0.0f; +} + + +status_t +BListTypeHandler::CreateValueNode(ValueNodeChild* nodeChild, Type* type, + ValueNode*& _node) +{ + if (SupportsType(type) == 0.0f) + return B_BAD_VALUE; + + ValueNode* node = new(std::nothrow) BListValueNode(nodeChild, + type); + + if (node == NULL) + return B_NO_MEMORY; + + _node = node; + + return B_OK; +} diff --git a/src/apps/debugger/value/type_handlers/BListTypeHandler.h b/src/apps/debugger/value/type_handlers/BListTypeHandler.h new file mode 100644 index 0000000000..12f37546bd --- /dev/null +++ b/src/apps/debugger/value/type_handlers/BListTypeHandler.h @@ -0,0 +1,21 @@ +/* + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef BLIST_TYPE_HANDLER_H +#define BLIST_TYPE_HANDLER_H + + +#include "TypeHandler.h" + + +class BListTypeHandler : public TypeHandler { +public: + virtual ~BListTypeHandler(); + + virtual float SupportsType(Type* type); + virtual status_t CreateValueNode(ValueNodeChild* nodeChild, + Type* type, ValueNode*& _node); +}; + +#endif // BLIST_TYPE_HANDLER_H diff --git a/src/apps/debugger/value/value_nodes/BListValueNode.cpp b/src/apps/debugger/value/value_nodes/BListValueNode.cpp new file mode 100644 index 0000000000..167c8884c0 --- /dev/null +++ b/src/apps/debugger/value/value_nodes/BListValueNode.cpp @@ -0,0 +1,255 @@ +/* + * Copyright 2012, Rene Gollent, rene@gollent.com + * Distributed under the terms of the MIT License. + */ + + +#include "BListValueNode.h" + +#include + +#include + +#include "AddressValueNode.h" +#include "Architecture.h" +#include "StringValue.h" +#include "Tracing.h" +#include "Type.h" +#include "TypeLookupConstraints.h" +#include "ValueLoader.h" +#include "ValueLocation.h" +#include "ValueNodeContainer.h" + + +// maximum number of array elements to show by default +static const int64 kMaxArrayElementCount = 20; + + +//#pragma mark - BListValueNode::BListElementNodeChild + + +class BListValueNode::BListElementNodeChild : public ValueNodeChild { +public: + BListElementNodeChild(BListValueNode* parent, + int64 elementIndex, Type* type); + virtual ~BListElementNodeChild(); + + virtual const BString& Name() const { return fName; }; + virtual Type* GetType() const { return fType; }; + virtual ValueNode* Parent() const { return fParent; }; + + virtual status_t ResolveLocation(ValueLoader* valueLoader, + ValueLocation*& _location); + +private: + Type* fType; + BListValueNode* fParent; + int64 fElementIndex; + BString fName; +}; + + +BListValueNode::BListElementNodeChild::BListElementNodeChild( + BListValueNode* parent, int64 elementIndex, Type* type) + : + ValueNodeChild(), + fType(type), + fParent(parent), + fElementIndex(elementIndex), + fName() +{ + fType->AcquireReference(); + fParent->AcquireReference(); + fName.SetToFormat("[%" B_PRId64 "]", fElementIndex); +} + + +BListValueNode::BListElementNodeChild::~BListElementNodeChild() +{ + fType->ReleaseReference(); + fParent->ReleaseReference(); +} + + +status_t +BListValueNode::BListElementNodeChild::ResolveLocation( + ValueLoader* valueLoader, ValueLocation*& _location) +{ + uint8 addressSize = valueLoader->GetArchitecture()->AddressSize(); + ValueLocation* location = new(std::nothrow) ValueLocation(); + if (location == NULL) + return B_NO_MEMORY; + + + uint64 listAddress = fParent->fDataLocation.ToUInt64(); + listAddress += fElementIndex * addressSize; + + ValuePieceLocation piece; + piece.SetToMemory(listAddress); + piece.SetSize(addressSize); + location->AddPiece(piece); + + _location = location; + return B_OK; +} + + +//#pragma mark - BListValueNode + +BListValueNode::BListValueNode(ValueNodeChild* nodeChild, + Type* type) + : + ValueNode(nodeChild), + fType(type), + fLoader(NULL) +{ + fType->AcquireReference(); +} + + +BListValueNode::~BListValueNode() +{ + fType->ReleaseReference(); + for (int32 i = 0; i < fChildren.CountItems(); i++) + fChildren.ItemAt(i)->ReleaseReference(); + + delete fLoader; +} + + +Type* +BListValueNode::GetType() const +{ + return fType; +} + + +status_t +BListValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader, + ValueLocation*& _location, Value*& _value) +{ + // get the location + ValueLocation* location = NodeChild()->Location(); + if (location == NULL) + return B_BAD_VALUE; + + + // get the value type + type_code valueType; + if (valueLoader->GetArchitecture()->AddressSize() == 4) { + valueType = B_UINT32_TYPE; + TRACE_LOCALS(" -> 32 bit\n"); + } else { + valueType = B_UINT64_TYPE; + TRACE_LOCALS(" -> 64 bit\n"); + } + + // load the value data + + status_t error = B_OK; + _location = location; + _value = NULL; + + ValueLocation* memberLocation = NULL; + CompoundType* baseType = dynamic_cast(fType); + + for (int32 i = 0; i < baseType->CountDataMembers(); i++) { + DataMember* member = baseType->DataMemberAt(i); + if (strcmp(member->Name(), "fObjectList") == 0) { + error = baseType->ResolveDataMemberLocation(member, + *location, memberLocation); + if (error != B_OK) { + TRACE_LOCALS( + "BListValueNode::ResolvedLocationAndValue(): " + "failed to resolve location of header member: %s\n", + strerror(error)); + delete memberLocation; + return error; + } + + error = valueLoader->LoadValue(memberLocation, valueType, + false, fDataLocation); + delete memberLocation; + if (error != B_OK) + return error; + } else if (strcmp(member->Name(), "fItemCount") == 0) { + error = baseType->ResolveDataMemberLocation(member, + *location, memberLocation); + if (error != B_OK) { + TRACE_LOCALS( + "BListValueNode::ResolvedLocationAndValue(): " + "failed to resolve location of header member: %s\n", + strerror(error)); + delete memberLocation; + return error; + } + + BVariant listSize; + error = valueLoader->LoadValue(memberLocation, valueType, + false, listSize); + delete memberLocation; + if (error != B_OK) + return error; + + fItemCount = listSize.ToInt32(); + TRACE_LOCALS( + "BListValueNode::ResolvedLocationAndValue(): " + "detected list size %" B_PRId32 "\n", + fItemCount); + } + memberLocation = NULL; + } + + if (fLoader == NULL) { + fLoader = new(std::nothrow)ValueLoader(*valueLoader); + if (fLoader == NULL) + return B_NO_MEMORY; + } + + return B_OK; +} + + +status_t +BListValueNode::CreateChildren() +{ + BString typeName; + TypeLookupConstraints constraints; + constraints.SetTypeKind(TYPE_ADDRESS); + constraints.SetBaseTypeName("void"); + Type* type = NULL; + status_t result = fLoader->LookupTypeByName(typeName, constraints, type); + if (result != B_OK) + return result; + + for (int32 i = 0; i < fItemCount && i < kMaxArrayElementCount; i++) + { + BListElementNodeChild* child = + new(std::nothrow) BListElementNodeChild(this, i, type); + if (child == NULL) + return B_NO_MEMORY; + child->SetContainer(fContainer); + fChildren.AddItem(child); + } + + fChildrenCreated = true; + + if (fContainer != NULL) + fContainer->NotifyValueNodeChildrenCreated(this); + + return B_OK; +} + + +int32 +BListValueNode::CountChildren() const +{ + return fChildren.CountItems(); +} + + +ValueNodeChild* +BListValueNode::ChildAt(int32 index) const +{ + return fChildren.ItemAt(index); +} diff --git a/src/apps/debugger/value/value_nodes/BListValueNode.h b/src/apps/debugger/value/value_nodes/BListValueNode.h new file mode 100644 index 0000000000..252cf332e4 --- /dev/null +++ b/src/apps/debugger/value/value_nodes/BListValueNode.h @@ -0,0 +1,53 @@ +/* + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef BLIST_VALUE_NODE_H +#define BLIST_VALUE_NODE_H + + +#include +#include + +#include + +#include "ValueLocation.h" +#include "ValueNode.h" + + +class CompoundType; + + +class BListValueNode : public ValueNode { +public: + BListValueNode(ValueNodeChild* nodeChild, + Type* type); + virtual ~BListValueNode(); + + virtual Type* GetType() const; + virtual status_t ResolvedLocationAndValue( + ValueLoader* valueLoader, + ValueLocation*& _location, + Value*& _value); + + virtual bool ChildCreationNeedsValue() const + { return true; } + virtual status_t CreateChildren(); + virtual int32 CountChildren() const; + virtual ValueNodeChild* ChildAt(int32 index) const; + +private: + class BListElementNodeChild; + typedef BObjectList ChildNodeList; + +private: + + Type* fType; + ChildNodeList fChildren; + ValueLoader* fLoader; + BVariant fDataLocation; + int32 fItemCount; +}; + + +#endif // BLIST_VALUE_NODE_H