Author: anevilyak Date: 2011-06-10 03:58:39 +0200 (Fri, 10 Jun 2011) New Revision: 42080 Changeset: https://dev.haiku-os.org/changeset/42080 Added: haiku/trunk/src/apps/debugger/TeamMemoryBlockManager.cpp haiku/trunk/src/apps/debugger/TeamMemoryBlockManager.h haiku/trunk/src/apps/debugger/model/TeamMemoryBlock.cpp haiku/trunk/src/apps/debugger/model/TeamMemoryBlock.h haiku/trunk/src/apps/debugger/user_interface/gui/inspector_window/ haiku/trunk/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp haiku/trunk/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h haiku/trunk/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp haiku/trunk/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h Modified: haiku/trunk/src/apps/debugger/Jamfile haiku/trunk/src/apps/debugger/Jobs.cpp haiku/trunk/src/apps/debugger/Jobs.h haiku/trunk/src/apps/debugger/MessageCodes.h haiku/trunk/src/apps/debugger/TeamDebugger.cpp haiku/trunk/src/apps/debugger/TeamDebugger.h haiku/trunk/src/apps/debugger/user_interface/UserInterface.h Log: * Introduce TeamMemoryBlock[Manager]. These provide an interface to raw memory page data of the target team. * Jobs: Add RetrieveMemoryBlockJob which performs a background read of the target team's memory. Used by InspectRequested() to perform the actual work. * TeamDebugger: Added InspectRequested() hooks to allow clients to ask for a memory read to be performed. * Introduce InspectorWindow and MemoryView to form the basis of a memory inspector. As yet these are more or less stubs and not yet hooked in. Modified: haiku/trunk/src/apps/debugger/Jamfile =================================================================== --- haiku/trunk/src/apps/debugger/Jamfile 2011-06-10 01:55:12 UTC (rev 42079) +++ haiku/trunk/src/apps/debugger/Jamfile 2011-06-10 01:58:39 UTC (rev 42080) @@ -20,6 +20,7 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) types ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui inspector_window ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui model ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui team_window ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui teams_window ] ; @@ -54,6 +55,7 @@ BreakpointManager.cpp Debugger.cpp Jobs.cpp + TeamMemoryBlockManager.cpp TeamDebugger.cpp ThreadHandler.cpp Worker.cpp @@ -127,6 +129,7 @@ UserBreakpoint.cpp Team.cpp TeamMemory.cpp + TeamMemoryBlock.cpp Thread.cpp ThreadInfo.cpp Type.cpp @@ -167,6 +170,10 @@ VariablesViewState.cpp VariablesViewStateHistory.cpp + # user_interface/gui/inspector_window + InspectorWindow.cpp + MemoryView.cpp + # user_interface/gui/teams_window TeamsWindow.cpp TeamsListView.cpp @@ -253,7 +260,7 @@ libshared.a $(TARGET_LIBSTDC++) - be tracker libdebug.so + be tracker libdebug.so libshared.a libexpression_parser.a libmapm.a : Debugger.rdef ; Modified: haiku/trunk/src/apps/debugger/Jobs.cpp =================================================================== --- haiku/trunk/src/apps/debugger/Jobs.cpp 2011-06-10 01:55:12 UTC (rev 42079) +++ haiku/trunk/src/apps/debugger/Jobs.cpp 2011-06-10 01:58:39 UTC (rev 42080) @@ -24,6 +24,8 @@ #include "StackFrameValues.h" #include "StackTrace.h" #include "Team.h" +#include "TeamMemory.h" +#include "TeamMemoryBlock.h" #include "TeamDebugInfo.h" #include "Thread.h" #include "Tracing.h" @@ -633,3 +635,41 @@ return nodeResolutionState != VALUE_NODE_UNRESOLVED ? nodeResolutionState : B_ERROR; } + + +RetrieveMemoryBlockJob::RetrieveMemoryBlockJob(TeamMemory* teamMemory, + TeamMemoryBlock* memoryBlock) + : + fKey(memoryBlock, JOB_TYPE_GET_MEMORY_BLOCK), + fTeamMemory(teamMemory), + fMemoryBlock(memoryBlock) +{ + fMemoryBlock->AcquireReference(); +} + + +RetrieveMemoryBlockJob::~RetrieveMemoryBlockJob() +{ + fMemoryBlock->ReleaseReference(); +} + + +const JobKey& +RetrieveMemoryBlockJob::Key() const +{ + return fKey; +} + + +status_t +RetrieveMemoryBlockJob::Do() +{ + + ssize_t result = fTeamMemory->ReadMemory(fMemoryBlock->BaseAddress(), + fMemoryBlock->Data(), fMemoryBlock->Size()); + if (result < 0) + return result; + + fMemoryBlock->MarkValid(); + return B_OK; +} Modified: haiku/trunk/src/apps/debugger/Jobs.h =================================================================== --- haiku/trunk/src/apps/debugger/Jobs.h 2011-06-10 01:55:12 UTC (rev 42079) +++ haiku/trunk/src/apps/debugger/Jobs.h 2011-06-10 01:58:39 UTC (rev 42080) @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxxx * Distributed under the terms of the MIT License. */ #ifndef JOBS_H @@ -7,6 +8,7 @@ #include "ImageDebugInfoProvider.h" +#include "Types.h" #include "Worker.h" @@ -20,6 +22,8 @@ class StackFrame; class StackFrameValues; class Team; +class TeamMemory; +class TeamMemoryBlock; class Thread; class Type; class TypeComponentPath; @@ -38,7 +42,8 @@ JOB_TYPE_LOAD_IMAGE_DEBUG_INFO, JOB_TYPE_LOAD_SOURCE_CODE, JOB_TYPE_GET_STACK_FRAME_VALUE, - JOB_TYPE_RESOLVE_VALUE_NODE_VALUE + JOB_TYPE_RESOLVE_VALUE_NODE_VALUE, + JOB_TYPE_GET_MEMORY_BLOCK }; @@ -177,4 +182,21 @@ }; +class RetrieveMemoryBlockJob : public Job { +public: + RetrieveMemoryBlockJob( + TeamMemory* teamMemory, + TeamMemoryBlock* memoryBlock); + virtual ~RetrieveMemoryBlockJob(); + + virtual const JobKey& Key() const; + virtual status_t Do(); + +private: + SimpleJobKey fKey; + TeamMemory* fTeamMemory; + TeamMemoryBlock* fMemoryBlock; +}; + + #endif // JOBS_H Modified: haiku/trunk/src/apps/debugger/MessageCodes.h =================================================================== --- haiku/trunk/src/apps/debugger/MessageCodes.h 2011-06-10 01:55:12 UTC (rev 42079) +++ haiku/trunk/src/apps/debugger/MessageCodes.h 2011-06-10 01:58:39 UTC (rev 42080) @@ -44,7 +44,9 @@ MSG_TEAM_DEBUGGER_QUIT = 'dbqt', MSG_SHOW_TEAMS_WINDOW = 'stsw', MSG_TEAMS_WINDOW_CLOSED = 'tswc', - MSG_DEBUG_THIS_TEAM = 'dbtt' + MSG_DEBUG_THIS_TEAM = 'dbtt', + MSG_INSPECTOR_WINDOW_CLOSED = 'irwc', + MSG_INSPECT_ADDRESS = 'isad' }; Modified: haiku/trunk/src/apps/debugger/TeamDebugger.cpp =================================================================== --- haiku/trunk/src/apps/debugger/TeamDebugger.cpp 2011-06-10 01:55:12 UTC (rev 42079) +++ haiku/trunk/src/apps/debugger/TeamDebugger.cpp 2011-06-10 01:58:39 UTC (rev 42080) @@ -14,6 +14,7 @@ #include <Message.h> +#include <ExpressionParser.h> #include <AutoLocker.h> #include "debug_utils.h" @@ -37,6 +38,8 @@ #include "Statement.h" #include "SymbolInfo.h" #include "TeamDebugInfo.h" +#include "TeamMemoryBlock.h" +#include "TeamMemoryBlockManager.h" #include "TeamSettings.h" #include "Tracing.h" #include "ValueNode.h" @@ -446,6 +449,26 @@ break; } + case MSG_INSPECT_ADDRESS: + { + TeamMemoryBlock::Listener* listener; + if (message->FindPointer("listener", + reinterpret_cast<void **>(&listener)) != B_OK) { + break; + } + + const char* addressExpression; + target_addr_t address; + if (message->FindString("addressExpression", + &addressExpression) == B_OK) { + _HandleInspectAddress(addressExpression, listener); + } else if (message->FindUInt64("address", + &address) == B_OK) { + _HandleInspectAddress(address, listener); + } + break; + } + case MSG_THREAD_STATE_CHANGED: { int32 threadID; @@ -661,6 +684,28 @@ } +void +TeamDebugger::InspectRequested(const char* addressExpression, + TeamMemoryBlock::Listener *listener) +{ + BMessage message(MSG_INSPECT_ADDRESS); + message.AddString("addressExpression", addressExpression); + message.AddPointer("listener", listener); + PostMessage(&message); +} + + +void +TeamDebugger::InspectRequested(target_addr_t address, + TeamMemoryBlock::Listener *listener) +{ + BMessage message(MSG_INSPECT_ADDRESS); + message.AddUInt64("address", address); + message.AddPointer("listener", listener); + PostMessage(&message); +} + + bool TeamDebugger::UserInterfaceQuitRequested() { @@ -1243,6 +1288,68 @@ } +void +TeamDebugger::_HandleInspectAddress(const char* addressExpression, + TeamMemoryBlock::Listener* listener) +{ + TRACE_CONTROL("TeamDebugger::_HandleInspectAddress(%s, %p)\n", + addressExpression, listener); + + ExpressionParser parser; + parser.SetSupportHexInput(true); + target_addr_t address = 0LL; + try { + address = parser.EvaluateToInt64(addressExpression); + } catch(ParseException parseError) { + _NotifyUser("Inspect Address", "Failed to parse address: %s", + parseError.message.String()); + return; + } catch(...) { + _NotifyUser("Inspect Address", "Unknown error while parsing address"); + return; + } + + _HandleInspectAddress(address, listener); +} + + +void +TeamDebugger::_HandleInspectAddress(target_addr_t address, + TeamMemoryBlock::Listener* listener) +{ + TRACE_CONTROL("TeamDebugger::_HandleInspectAddress(" B_PRIx64 ", %p)\n", + addressExpression, listener); + + TeamMemoryBlock* memoryBlock = fMemoryBlockManager + ->GetMemoryBlock(address); + + if (memoryBlock == NULL) { + _NotifyUser("Inspect Address", "Failed to allocate memory block"); + return; + } + + if (!memoryBlock->HasListener(listener)) + memoryBlock->AddListener(listener); + + if (!memoryBlock->IsValid()) { + AutoLocker< ::Team> teamLocker(fTeam); + + TeamMemory* memory = fTeam->GetTeamMemory(); + // schedule the job + status_t result; + if ((result = fWorker->ScheduleJob( + new(std::nothrow) RetrieveMemoryBlockJob(memory, memoryBlock), + this)) != B_OK) { + memoryBlock->ReleaseReference(); + _NotifyUser("Inspect Address", "Failed to retrieve memory data: %s", + strerror(result)); + } + } else + memoryBlock->NotifyDataRetrieved(); + +} + + ThreadHandler* TeamDebugger::_GetThreadHandler(thread_id threadID) { Modified: haiku/trunk/src/apps/debugger/TeamDebugger.h =================================================================== --- haiku/trunk/src/apps/debugger/TeamDebugger.h 2011-06-10 01:55:12 UTC (rev 42079) +++ haiku/trunk/src/apps/debugger/TeamDebugger.h 2011-06-10 01:58:39 UTC (rev 42080) @@ -22,6 +22,7 @@ class FileManager; class SettingsManager; class TeamDebugInfo; +class TeamMemoryBlockManager; class TeamDebugger : public BLooper, private UserInterfaceListener, @@ -65,6 +66,10 @@ virtual void ClearBreakpointRequested(target_addr_t address); virtual void ClearBreakpointRequested( UserBreakpoint* breakpoint); + virtual void InspectRequested(target_addr_t address, + TeamMemoryBlock::Listener* listener); + virtual void InspectRequested(const char* addressExpression, + TeamMemoryBlock::Listener* listener); virtual bool UserInterfaceQuitRequested(); // JobListener @@ -118,6 +123,13 @@ void _HandleClearUserBreakpoint( UserBreakpoint* breakpoint); + void _HandleInspectAddress( + target_addr_t address, + TeamMemoryBlock::Listener* listener); + void _HandleInspectAddress( + const char* addressExpression, + TeamMemoryBlock::Listener* listener); + ThreadHandler* _GetThreadHandler(thread_id threadID); status_t _AddImage(const ImageInfo& imageInfo, @@ -142,6 +154,8 @@ FileManager* fFileManager; Worker* fWorker; BreakpointManager* fBreakpointManager; + TeamMemoryBlockManager* + fMemoryBlockManager; thread_id fDebugEventListener; UserInterface* fUserInterface; volatile bool fTerminating; Added: haiku/trunk/src/apps/debugger/TeamMemoryBlockManager.cpp =================================================================== --- haiku/trunk/src/apps/debugger/TeamMemoryBlockManager.cpp (rev 0) +++ haiku/trunk/src/apps/debugger/TeamMemoryBlockManager.cpp 2011-06-10 01:58:39 UTC (rev 42080) @@ -0,0 +1,208 @@ +/* + * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "TeamMemoryBlockManager.h" + +#include <new> + +#include <AutoDeleter.h> +#include <AutoLocker.h> + +#include "TeamMemoryBlock.h" + + +struct TeamMemoryBlockManager::Key { + target_addr_t address; + + Key(target_addr_t address) + : + address(address) + { + } + + uint32 HashValue() const + { + return (uint32)address; + } + + bool operator==(const Key& other) const + { + return address == other.address; + } +}; + + +struct TeamMemoryBlockManager::MemoryBlockEntry : Key { + TeamMemoryBlock* block; + MemoryBlockEntry* next; + + MemoryBlockEntry(TeamMemoryBlock* block) + : + Key(block->BaseAddress()), + block(block) + { + block->AcquireReference(); + } + + ~MemoryBlockEntry() + { + block->ReleaseReference(); + } +}; + + +struct TeamMemoryBlockManager::MemoryBlockHashDefinition { + typedef Key KeyType; + typedef MemoryBlockEntry ValueType; + + size_t HashKey(const Key& key) const + { + return key.HashValue(); + } + + size_t Hash(const MemoryBlockEntry* value) const + { + return value->HashValue(); + } + + bool Compare(const Key& key, const MemoryBlockEntry* value) const + { + return key == *value; + } + + MemoryBlockEntry*& GetLink(MemoryBlockEntry* value) const + { + return value->next; + } +}; + + +TeamMemoryBlockManager::TeamMemoryBlockManager() + : + fActiveBlocks(NULL), + fDeadBlocks(NULL) +{ +} + + +TeamMemoryBlockManager::~TeamMemoryBlockManager() +{ + _Cleanup(); +} + + +status_t +TeamMemoryBlockManager::Init() +{ + status_t result = fLock.InitCheck(); + if (result != B_OK) + return result; + + fActiveBlocks = new(std::nothrow) MemoryBlockTable(); + if (fActiveBlocks == NULL) + return B_NO_MEMORY; + ObjectDeleter<MemoryBlockTable> activeDeleter(fActiveBlocks); + result = fActiveBlocks->Init(); + if (result != B_OK) + return result; + + fDeadBlocks = new(std::nothrow) MemoryBlockTable(); + if (fDeadBlocks == NULL) + return B_NO_MEMORY; + ObjectDeleter<MemoryBlockTable> deadDeleter(fDeadBlocks); + result = fDeadBlocks->Init(); + if (result != B_OK) + return result; + + activeDeleter.Detach(); + deadDeleter.Detach(); + + return B_OK; +} + + +TeamMemoryBlock* +TeamMemoryBlockManager::GetMemoryBlock(target_addr_t address) +{ + AutoLocker<BLocker> lock(fLock); + + address &= ~B_PAGE_SIZE - 1; + MemoryBlockEntry* entry = fActiveBlocks->Lookup(address); + if (entry == NULL) { + TeamMemoryBlock* block = new(std::nothrow) TeamMemoryBlock(address, + this); + if (block == NULL) + return NULL; + + entry = new(std::nothrow) MemoryBlockEntry(block); + if (entry == NULL) { + delete block; + return NULL; + } + + fActiveBlocks->Insert(entry); + } + + int32 refCount = entry->block->AcquireReference(); + if (refCount == 0) { + // this block already had its last reference released, + // move it to the dead list and retrieve a new one instead. + _MarkDeadBlock(address); + return GetMemoryBlock(address); + } + + return entry->block; +} + + +void +TeamMemoryBlockManager::_Cleanup() +{ + if (fActiveBlocks != NULL) { + MemoryBlockEntry* entry = fActiveBlocks->Clear(true); + + while (entry != NULL) { + MemoryBlockEntry* next = entry->next; + delete entry; + entry = next; + } + + delete fActiveBlocks; + fActiveBlocks = NULL; + } +} + + +void +TeamMemoryBlockManager::_MarkDeadBlock(target_addr_t address) +{ + AutoLocker<BLocker> lock(fLock); + MemoryBlockEntry* entry = fActiveBlocks->Lookup(address); + if (entry != NULL) { + fActiveBlocks->Remove(entry); + fDeadBlocks->Insert(entry); + } +} + + +void +TeamMemoryBlockManager::_RemoveBlock(target_addr_t address) +{ + AutoLocker<BLocker> lock(fLock); + MemoryBlockEntry* entry = fActiveBlocks->Lookup(address); + if (entry != NULL) { + fActiveBlocks->Remove(entry); + delete entry; + return; + } + + entry = fDeadBlocks->Lookup(address); + if (entry != NULL) { + fDeadBlocks->Remove(entry); + delete entry; + } +} + Added: haiku/trunk/src/apps/debugger/TeamMemoryBlockManager.h =================================================================== --- haiku/trunk/src/apps/debugger/TeamMemoryBlockManager.h (rev 0) +++ haiku/trunk/src/apps/debugger/TeamMemoryBlockManager.h 2011-06-10 01:58:39 UTC (rev 42080) @@ -0,0 +1,50 @@ +/* + * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ +#ifndef TEAM_MEMORY_BLOCK_MANAGER_H +#define TEAM_MEMORY_BLOCK_MANAGER_H + + +#include <Locker.h> +#include <Referenceable.h> +#include <util/OpenHashTable.h> + +#include "Types.h" + +struct MemoryBlockHashDefinition; +class TeamMemoryBlock; + + +class TeamMemoryBlockManager +{ +public: + TeamMemoryBlockManager(); + ~TeamMemoryBlockManager(); + + status_t Init(); + + TeamMemoryBlock* GetMemoryBlock(target_addr_t address); + +private: + struct Key; + struct MemoryBlockEntry; + struct MemoryBlockHashDefinition; + typedef BOpenHashTable<MemoryBlockHashDefinition> MemoryBlockTable; + +private: + void _Cleanup(); + void _MarkDeadBlock(target_addr_t address); + void _RemoveBlock(target_addr_t address); + +private: + friend class TeamMemoryBlock; + +private: + BLocker fLock; + MemoryBlockTable* fActiveBlocks; + MemoryBlockTable* fDeadBlocks; +}; + + +#endif // TEAM_MEMORY_BLOCK_MANAGER_H Added: haiku/trunk/src/apps/debugger/model/TeamMemoryBlock.cpp =================================================================== --- haiku/trunk/src/apps/debugger/model/TeamMemoryBlock.cpp (rev 0) +++ haiku/trunk/src/apps/debugger/model/TeamMemoryBlock.cpp 2011-06-10 01:58:39 UTC (rev 42080) @@ -0,0 +1,108 @@ +/* + * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "TeamMemoryBlock.h" + + +#include <AutoLocker.h> + +#include "TeamMemoryBlockManager.h" + + +// #pragma mark - TeamMemoryBlock + + +TeamMemoryBlock::TeamMemoryBlock(target_addr_t baseAddress, + TeamMemoryBlockManager* manager) + : + fValid(false), + fBaseAddress(baseAddress), + fBlockManager(manager) +{ +} + + +TeamMemoryBlock::~TeamMemoryBlock() +{ +} + + +void +TeamMemoryBlock::AddListener(Listener* listener) +{ + AutoLocker<BLocker> lock(fLock); + fListeners.Add(listener); +} + + +bool +TeamMemoryBlock::HasListener(Listener* listener) +{ + AutoLocker<BLocker> lock(fLock); + ListenerList::Iterator iterator = fListeners.GetIterator(); + while (iterator.HasNext()) { + if (iterator.Next() == listener) + return true; + } + + return false; +} + + +void +TeamMemoryBlock::RemoveListener(Listener* listener) +{ + AutoLocker<BLocker> lock(fLock); + fListeners.Remove(listener); +} + + +void +TeamMemoryBlock::MarkValid() +{ + fValid = true; + NotifyDataRetrieved(); +} + + +void +TeamMemoryBlock::Invalidate() +{ + fValid = false; +} + + +void +TeamMemoryBlock::NotifyDataRetrieved() +{ + for (ListenerList::Iterator it = fListeners.GetIterator(); + Listener* listener = it.Next();) { + listener->MemoryBlockRetrieved(this); + } +} + + +void +TeamMemoryBlock::LastReferenceReleased() +{ + fBlockManager->_RemoveBlock(fBaseAddress); + + BReferenceable::LastReferenceReleased(); +} + + +// #pragma mark - TeamMemoryBlock + + +TeamMemoryBlock::Listener::~Listener() +{ +} + + +void +TeamMemoryBlock::Listener::MemoryBlockRetrieved(TeamMemoryBlock* block) +{ +} Added: haiku/trunk/src/apps/debugger/model/TeamMemoryBlock.h =================================================================== --- haiku/trunk/src/apps/debugger/model/TeamMemoryBlock.h (rev 0) +++ haiku/trunk/src/apps/debugger/model/TeamMemoryBlock.h 2011-06-10 01:58:39 UTC (rev 42080) @@ -0,0 +1,70 @@ +/* + * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ +#ifndef TEAM_MEMORY_BLOCK_H +#define TEAM_MEMORY_BLOCK_H + + +#include <OS.h> + +#include <Locker.h> +#include <Referenceable.h> +#include <util/DoublyLinkedList.h> + +#include "Types.h" + + +class TeamMemoryBlockManager; + + +class TeamMemoryBlock : public BReferenceable { +public: + class Listener; + +public: + TeamMemoryBlock(target_addr_t baseAddress, + TeamMemoryBlockManager* manager); + ~TeamMemoryBlock(); + + void AddListener(Listener* listener); + bool HasListener(Listener* listener); + void RemoveListener(Listener* listener); + + bool IsValid() const { return fValid; }; + void MarkValid(); + void Invalidate(); + + target_addr_t BaseAddress() const { return fBaseAddress; }; + uint8* Data() { return fData; }; + size_t Size() const { return sizeof(fData); }; + + void NotifyDataRetrieved(); + +protected: + virtual void LastReferenceReleased(); + +private: + typedef DoublyLinkedList<Listener> ListenerList; + +private: + bool fValid; + target_addr_t fBaseAddress; + uint8 fData[B_PAGE_SIZE]; + ListenerList fListeners; + TeamMemoryBlockManager* + fBlockManager; + BLocker fLock; +}; + + +class TeamMemoryBlock::Listener : public DoublyLinkedListLinkImpl<Listener> { +public: + virtual ~Listener(); + + virtual void MemoryBlockRetrieved(TeamMemoryBlock* block); +}; + + +#endif // TEAM_MEMORY_BLOCK_H + Modified: haiku/trunk/src/apps/debugger/user_interface/UserInterface.h =================================================================== --- haiku/trunk/src/apps/debugger/user_interface/UserInterface.h 2011-06-10 01:55:12 UTC (rev 42079) +++ haiku/trunk/src/apps/debugger/user_interface/UserInterface.h 2011-06-10 01:58:39 UTC (rev 42080) @@ -10,6 +10,7 @@ #include <Referenceable.h> +#include "TeamMemoryBlock.h" #include "Types.h" @@ -82,6 +83,13 @@ UserBreakpoint* breakpoint) = 0; // TODO: Consolidate those! + virtual void InspectRequested( + target_addr_t address, + TeamMemoryBlock::Listener* listener) = 0; + virtual void InspectRequested( + const char* addressExpression, + TeamMemoryBlock::Listener* listener) = 0; + virtual bool UserInterfaceQuitRequested() = 0; }; Added: haiku/trunk/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp =================================================================== --- haiku/trunk/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp (rev 0) +++ haiku/trunk/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp 2011-06-10 01:58:39 UTC (rev 42080) @@ -0,0 +1,92 @@ +/* + * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxxx All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#include "InspectorWindow.h" + +#include <Application.h> +#include <Button.h> +#include <LayoutBuilder.h> +#include <ScrollView.h> +#include <TextControl.h> + +#include <stdio.h> + +#include "MemoryView.h" +#include "MessageCodes.h" +#include "UserInterface.h" + + +InspectorWindow::InspectorWindow(UserInterfaceListener* listener) + : + BWindow(BRect(100, 100, 500, 250), "Inspector", B_DOCUMENT_WINDOW, + B_ASYNCHRONOUS_CONTROLS), + fListener(listener) +{ +} + + +InspectorWindow::~InspectorWindow() +{ +} + + +/* static */ InspectorWindow* +InspectorWindow::Create(UserInterfaceListener* listener) +{ + InspectorWindow* self = new InspectorWindow(listener); + + try { + self->_Init(); + } catch (...) { + delete self; + throw; + } + + return self; +} + + +void +InspectorWindow::_Init() +{ + BLayoutBuilder::Group<>(this, B_VERTICAL) + .Add(fAddressInput = new BTextControl("addrInput", + "Target Address:", "", + new BMessage(MSG_INSPECT_ADDRESS))) + .Add(fMemoryView = new MemoryView(NULL, NULL)) + .End(); + + fAddressInput->SetTarget(this); +} + + + +void +InspectorWindow::MessageReceived(BMessage* msg) +{ + switch (msg->what) { + case MSG_INSPECT_ADDRESS: + { + const char* addressExpression = fAddressInput->Text(); + fListener->InspectRequested(addressExpression, this); + break; + } + } +} + + +bool +InspectorWindow::QuitRequested() +{ + be_app_messenger.SendMessage(MSG_INSPECTOR_WINDOW_CLOSED); + return true; +} + + +void +InspectorWindow::MemoryBlockRetrieved(TeamMemoryBlock* block) +{ + // TODO: implement +} Added: haiku/trunk/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h =================================================================== --- haiku/trunk/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h (rev 0) +++ haiku/trunk/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h 2011-06-10 01:58:39 UTC (rev 42080) @@ -0,0 +1,45 @@ +/* + * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxxx All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef INSPECTOR_WINDOW_H +#define INSPECTOR_WINDOW_H + + +#include <Window.h> + +#include "TeamMemoryBlock.h" +#include "Types.h" + + +class BButton; +class BTextControl; +class MemoryView; +class UserInterfaceListener; + + +class InspectorWindow : public BWindow, + public TeamMemoryBlock::Listener { +public: + InspectorWindow( + UserInterfaceListener* listener); + virtual ~InspectorWindow(); + + static InspectorWindow* Create(UserInterfaceListener* listener); + // throws + + virtual void MessageReceived(BMessage* message); + virtual bool QuitRequested(); + + virtual void MemoryBlockRetrieved(TeamMemoryBlock* block); [... truncated: 177 lines follow ...]