[haiku-commits] r42080 - in haiku/trunk/src/apps/debugger: . model user_interface user_interface/gui user_interface/gui/inspector_window

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 10 Jun 2011 03:58:40 +0200 (CEST)

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 ...]

Other related posts: