From 04584c0d6f9eb1cc69fe36df2a761a13ede381da Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 21 Jun 2011 22:59:54 +0000 Subject: [PATCH] Add the beginnings of a BMessage type/value handler. Not yet registered with the type handler roster since it's quite far from being complete. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42279 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/debugger/Jamfile | 2 + src/apps/debugger/value/TypeHandlerRoster.cpp | 31 +++-- src/apps/debugger/value/ValueLoader.cpp | 13 ++ src/apps/debugger/value/ValueLoader.h | 3 + .../type_handlers/BMessageTypeHandler.cpp | 68 +++++++++++ .../value/type_handlers/BMessageTypeHandler.h | 21 ++++ .../value/value_nodes/BMessageValueNode.cpp | 115 ++++++++++++++++++ .../value/value_nodes/BMessageValueNode.h | 33 +++++ 8 files changed, 274 insertions(+), 12 deletions(-) create mode 100644 src/apps/debugger/value/type_handlers/BMessageTypeHandler.cpp create mode 100644 src/apps/debugger/value/type_handlers/BMessageTypeHandler.h create mode 100644 src/apps/debugger/value/value_nodes/BMessageValueNode.cpp create mode 100644 src/apps/debugger/value/value_nodes/BMessageValueNode.h diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 814100e893..f64e1fe353 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -220,6 +220,7 @@ Application Debugger : ValueNodeContainer.cpp # value/type_handlers + BMessageTypeHandler.cpp CStringTypeHandler.cpp # value/value_handlers @@ -233,6 +234,7 @@ Application Debugger : # value/value_nodes AddressValueNode.cpp ArrayValueNode.cpp + BMessageValueNode.cpp CompoundValueNode.cpp CStringValueNode.cpp EnumerationValueNode.cpp diff --git a/src/apps/debugger/value/TypeHandlerRoster.cpp b/src/apps/debugger/value/TypeHandlerRoster.cpp index 147be0377b..e37852e12b 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 "BMessageTypeHandler.h" #include "CStringTypeHandler.h" #include "EnumerationValueNode.h" #include "PointerToMemberValueNode.h" @@ -126,25 +127,31 @@ TypeHandlerRoster::RegisterDefaultHandlers() TypeHandler* handler; BReference handlerReference; - #undef REGISTER_HANDLER - #define REGISTER_HANDLER(name) \ + #undef REGISTER_BASIC_HANDLER + #define REGISTER_BASIC_HANDLER(name) \ handler = new(std::nothrow) \ BasicTypeHandler(); \ handlerReference.SetTo(handler, true); \ if (handler == NULL || !RegisterHandler(handler)) \ return B_NO_MEMORY; - REGISTER_HANDLER(Address); - REGISTER_HANDLER(Array); - REGISTER_HANDLER(Compound); - REGISTER_HANDLER(Enumeration); - REGISTER_HANDLER(PointerToMember); - REGISTER_HANDLER(Primitive); + REGISTER_BASIC_HANDLER(Address); + REGISTER_BASIC_HANDLER(Array); + REGISTER_BASIC_HANDLER(Compound); + REGISTER_BASIC_HANDLER(Enumeration); + REGISTER_BASIC_HANDLER(PointerToMember); + REGISTER_BASIC_HANDLER(Primitive); - handler = new(std::nothrow) CStringTypeHandler(); - handlerReference.SetTo(handler, true); - if (handler == NULL || !RegisterHandler(handler)) - return B_NO_MEMORY; + #undef REGISTER_SPECIALIZED_HANDLER + #define REGISTER_SPECIALIZED_HANDLER(name) \ + handler = new(std::nothrow) \ + name##TypeHandler(); \ + handlerReference.SetTo(handler, true); \ + if (handler == NULL || !RegisterHandler(handler)) \ + return B_NO_MEMORY; + + REGISTER_SPECIALIZED_HANDLER(CString); +// REGISTER_SPECIALIZED_HANDLER(BMessage); return B_OK; } diff --git a/src/apps/debugger/value/ValueLoader.cpp b/src/apps/debugger/value/ValueLoader.cpp index 20773d660e..ef24e9521d 100644 --- a/src/apps/debugger/value/ValueLoader.cpp +++ b/src/apps/debugger/value/ValueLoader.cpp @@ -187,6 +187,19 @@ ValueLoader::LoadValue(ValueLocation* location, type_code valueType, } +status_t +ValueLoader::LoadRawValue(BVariant& location, size_t bytesToRead, void* _value) +{ + ssize_t bytesRead = fTeamMemory->ReadMemory(location.ToUInt64(), + _value, bytesToRead); + if (bytesRead < 0) + return bytesRead; + if ((uint32)bytesRead != bytesToRead) + return B_BAD_ADDRESS; + return B_OK; +} + + status_t ValueLoader::LoadStringValue(BVariant& location, size_t maxSize, BString& _value) { diff --git a/src/apps/debugger/value/ValueLoader.h b/src/apps/debugger/value/ValueLoader.h index 6f39e56672..5a1eb4c676 100644 --- a/src/apps/debugger/value/ValueLoader.h +++ b/src/apps/debugger/value/ValueLoader.h @@ -31,6 +31,9 @@ public: type_code valueType, bool shortValueIsFine, BVariant& _value); + status_t LoadRawValue(BVariant& location, + size_t maxSize, void* _value); + status_t LoadStringValue(BVariant& location, size_t maxSize, BString& _value); diff --git a/src/apps/debugger/value/type_handlers/BMessageTypeHandler.cpp b/src/apps/debugger/value/type_handlers/BMessageTypeHandler.cpp new file mode 100644 index 0000000000..d29605d32a --- /dev/null +++ b/src/apps/debugger/value/type_handlers/BMessageTypeHandler.cpp @@ -0,0 +1,68 @@ +/* + * Copyright 2011, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "BMessageTypeHandler.h" + +#include + +#include "BMessageValueNode.h" +#include "Type.h" + + +BMessageTypeHandler::~BMessageTypeHandler() +{ +} + + +float +BMessageTypeHandler::SupportsType(Type* type) +{ + AddressType* addressType = dynamic_cast(type); + CompoundType* baseType = dynamic_cast(type); + ModifiedType* modifiedType = NULL; + if (addressType != NULL && addressType->AddressKind() + == DERIVED_TYPE_POINTER) { + baseType = dynamic_cast( + addressType->BaseType()); + if (baseType == NULL) { + modifiedType = dynamic_cast( + addressType->BaseType()); + } + } + + if (baseType == NULL && modifiedType == NULL) + return 0.0f; + else if (modifiedType != NULL) { + baseType = dynamic_cast( + modifiedType->ResolveRawType(false)); + if (baseType == NULL) + return 0.0f; + } + + if (baseType->ResolveRawType(true)->Name() == "BMessage") + return 1.0f; + + return 0.0f; +} + + +status_t +BMessageTypeHandler::CreateValueNode(ValueNodeChild* nodeChild, Type* type, + ValueNode*& _node) +{ + if (SupportsType(type) == 0.0f) + return B_BAD_VALUE; + + ValueNode* node = new(std::nothrow) BMessageValueNode(nodeChild, + type); + + if (node == NULL) + return B_NO_MEMORY; + + _node = node; + + return B_OK; +} diff --git a/src/apps/debugger/value/type_handlers/BMessageTypeHandler.h b/src/apps/debugger/value/type_handlers/BMessageTypeHandler.h new file mode 100644 index 0000000000..321672e314 --- /dev/null +++ b/src/apps/debugger/value/type_handlers/BMessageTypeHandler.h @@ -0,0 +1,21 @@ +/* + * Copyright 2011, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef BMESSAGE_TYPE_HANDLER_H +#define BMESSAGE_TYPE_HANDLER_H + + +#include "TypeHandler.h" + + +class BMessageTypeHandler : public TypeHandler { +public: + virtual ~BMessageTypeHandler(); + + virtual float SupportsType(Type* type); + virtual status_t CreateValueNode(ValueNodeChild* nodeChild, + Type* type, ValueNode*& _node); +}; + +#endif // BMESSAGE_TYPE_HANDLER_H diff --git a/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp b/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp new file mode 100644 index 0000000000..c271269421 --- /dev/null +++ b/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 2011, Rene Gollent, rene@gollent.com + * Distributed under the terms of the MIT License. + */ + + +#include "BMessageValueNode.h" + +#include + +#include + +#include "Architecture.h" +#include "StringValue.h" +#include "Tracing.h" +#include "Type.h" +#include "ValueLoader.h" +#include "ValueLocation.h" +#include "ValueNodeContainer.h" + + +// #pragma mark - BMessageValueNode + + +BMessageValueNode::BMessageValueNode(ValueNodeChild* nodeChild, + Type* type) + : + ValueNode(nodeChild), + fType(type) +{ + fType->AcquireReference(); +} + + +BMessageValueNode::~BMessageValueNode() +{ + fType->ReleaseReference(); +} + + +Type* +BMessageValueNode::GetType() const +{ + return fType; +} + + +status_t +BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader, + ValueLocation*& _location, Value*& _value) +{ + // get the location + ValueLocation* location = NodeChild()->Location(); + if (location == NULL) + return B_BAD_VALUE; + + TRACE_LOCALS(" TYPE_ADDRESS (BMessage)\n"); + + // 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 + + BVariant addressData; + status_t error = B_OK; + if (dynamic_cast(fType) != NULL) { + error = valueLoader->LoadValue(location, valueType, false, + addressData); + } else + addressData.SetTo(location->PieceAt(0).address); + + + TRACE_LOCALS("Address: 0x%" B_PRIx64 "\n", addressData.ToUInt64()); + + uint8 buffer[sizeof(BMessage)]; + error = valueLoader->LoadRawValue(addressData, sizeof(BMessage), buffer); + if (error == B_OK) { + BMessage* message = (BMessage *)buffer; + TRACE_LOCALS("Loaded BMessage('%c%c%c%c')\n", + char((message->what >> 24) & 0xff), + char((message->what >> 16) & 0xff), + char((message->what >> 8) & 0xff), + char(message->what & 0xff)); + } + + return B_BAD_VALUE; +} + + +status_t +BMessageValueNode::CreateChildren() +{ + return B_OK; +} + + +int32 +BMessageValueNode::CountChildren() const +{ + return 0; +} + + +ValueNodeChild* +BMessageValueNode::ChildAt(int32 index) const +{ + return NULL; +} diff --git a/src/apps/debugger/value/value_nodes/BMessageValueNode.h b/src/apps/debugger/value/value_nodes/BMessageValueNode.h new file mode 100644 index 0000000000..fccfbc10e0 --- /dev/null +++ b/src/apps/debugger/value/value_nodes/BMessageValueNode.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef BMESSAGE_VALUE_NODE_H +#define BMESSAGE_VALUE_NODE_H + + +#include "ValueNode.h" + + +class BMessageValueNode : public ValueNode { +public: + BMessageValueNode(ValueNodeChild* nodeChild, + Type* type); + virtual ~BMessageValueNode(); + + virtual Type* GetType() const; + + virtual status_t ResolvedLocationAndValue( + ValueLoader* valueLoader, + ValueLocation*& _location, + Value*& _value); + + virtual status_t CreateChildren(); + virtual int32 CountChildren() const; + virtual ValueNodeChild* ChildAt(int32 index) const; + +private: + Type* fType; +}; + +#endif // BMESSAGE_VALUE_NODE_H