From 29a6c81bcd87a541b6e00462f24ca15e9b39654f Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Thu, 23 Jun 2011 00:08:58 +0000 Subject: [PATCH] We now retrieve and unflatten the target BMessage successfully, though we don't yet create child nodes for the contained fields. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42287 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../value/value_nodes/BMessageValueNode.cpp | 112 ++++++++++++++++-- 1 file changed, 100 insertions(+), 12 deletions(-) diff --git a/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp b/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp index 7f9584f3f0..af214157f1 100644 --- a/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp +++ b/src/apps/debugger/value/value_nodes/BMessageValueNode.cpp @@ -8,7 +8,9 @@ #include +#include #include +#include #include "Architecture.h" #include "StringValue.h" @@ -19,6 +21,39 @@ #include "ValueNodeContainer.h" +// minimal replica of BMessage's class structure for +// extracting fields +class BMessageValue { + public: + uint32 what; + + virtual ~BMessageValue(); + + struct message_header; + struct field_header; + + message_header* fHeader; + field_header* fFields; + uint8* fData; + + uint32 fFieldsAvailable; + size_t fDataAvailable; + + mutable BMessage* fOriginal; + + BMessage* fQueueLink; + // fQueueLink is used by BMessageQueue to build a linked list + + void* fArchivingPointer; + + uint32 fReserved[8]; + + virtual void _ReservedMessage1(); + virtual void _ReservedMessage2(); + virtual void _ReservedMessage3(); +}; + + // #pragma mark - BMessageValueNode @@ -77,21 +112,74 @@ BMessageValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader, addressData.SetTo(location->PieceAt(0).address); - TRACE_LOCALS("Address: 0x%" B_PRIx64 "\n", addressData.ToUInt64()); + TRACE_LOCALS("BMessage: Address: 0x%" B_PRIx64 "\n", + addressData.ToUInt64()); - uint8 buffer[sizeof(BMessage)]; - error = valueLoader->LoadRawValue(addressData, sizeof(BMessage), buffer); + uint8 classBuffer[sizeof(BMessage)]; + error = valueLoader->LoadRawValue(addressData, sizeof(BMessage), + classBuffer); + if (error != B_OK) + return error; -#if APPS_DEBUGGER_TRACE_STACK_FRAME_LOCALS - 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)); + BVariant headerAddress; + BMessageValue* value = (BMessageValue*)classBuffer; + headerAddress.SetTo((target_addr_t)value->fHeader); + + uint8 headerBuffer[sizeof(BMessage::message_header)]; + error = valueLoader->LoadRawValue(headerAddress, sizeof(headerBuffer), + headerBuffer); + TRACE_LOCALS("BMessage: Header Address: 0x%" B_PRIx64 ", result: %ld\n", + headerAddress.ToUInt64(), error); + if (error != B_OK) + return error; + + BMessage::message_header* header = (BMessage::message_header*)headerBuffer; + size_t fieldsSize = header->field_count * sizeof(BMessage::field_header); + size_t totalMessageSize = sizeof(BMessage::message_header) + + fieldsSize + header->data_size; + + uint8* messageBuffer = new(std::nothrow)uint8[totalMessageSize]; + if (messageBuffer == NULL) + return B_NO_MEMORY; + + memset(messageBuffer, 0, totalMessageSize); + + ArrayDeleter deleter(messageBuffer); + + // This more or less follows the logic of BMessage::Flatten + // in order to reconstruct the flattened buffer ; thus if the + // internal representation of that changes, this will have to + // follow suit + header->what = value->what; + uint8* currentBuffer = messageBuffer; + memcpy(currentBuffer, header, + sizeof(BMessage::message_header)); + + if (fieldsSize > 0) { + headerAddress.SetTo((target_addr_t)value->fFields); + currentBuffer += sizeof(BMessage::message_header); + error = valueLoader->LoadRawValue(headerAddress, fieldsSize, + currentBuffer); + TRACE_LOCALS("BMessage: Field Header Address: 0x%" B_PRIx64 + ", result: %ld\n", headerAddress.ToUInt64(), error); + if (error != B_OK) + return error; + + headerAddress.SetTo((target_addr_t)value->fData); + currentBuffer += fieldsSize; + error = valueLoader->LoadRawValue(headerAddress, header->data_size, + currentBuffer); + TRACE_LOCALS("BMessage: Data Address: 0x%" B_PRIx64 ", result: %ld\n", + headerAddress.ToUInt64(), error); + if (error != B_OK) + return B_ERROR; } -#endif + + BMessage message; + error = message.Unflatten((const char *)messageBuffer); + TRACE_LOCALS("BMessage: Unflatten result: %s\n", strerror(error)); + if (error != B_OK) + return error; return B_BAD_VALUE; }