[haiku-commits] haiku: hrev49189 - in src/apps/debugger: user_interface/gui/inspector_window controllers model jobs

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 23 May 2015 22:55:09 +0200 (CEST)

hrev49189 adds 7 changesets to branch 'master'
old head: 2994934b9271f2f6151dbfa90e8c4ea568b62b03
new head: 03796a0cefd2568ee7c7eb3f0a0164f7f48cc9b1
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=03796a0cefd2+%5E2994934b9271

----------------------------------------------------------------------------

40d8306053e0: Debugger: Fix inverted error check.

InspectorWindow:
- Fix inverted error check when retrieving settings. This was
causing us to fail to successfully load/apply previously stored
settings for the inspector.

82bf490fa6a4: Debugger: Fix MemoryView layout issues.

MemoryView:
- Implement {Min,Max,Preferred}Size() hooks. The default BView
versions were causing the inspector to sometimes not be properly
resizable after previous settings were restored.

5474c672709c: Debugger: Add page protection indicator to inspector.

InspectorWindow:
- We now display a label indicating if the currently inspected block
is writable or not, so the user knows whether it's possible to modify
the contents.

68e78ff84182: Debugger: Add memory write support.

- Implements various support classes and functions that will be
needed in order to marshal requests to write to memory in the
target team.

76ada671ba3b: Debugger: Extend MemoryView listener interface.

MemoryView::Listener:
- Add extra hooks for notifying listener of internal mode changes.
Implement accordingly in InspectorWindow.

6ce909030dbe: Debugger: Add edit mode support to MemoryView.

MemoryView:
- Add hooks and supporting status tracking members to enable edit mode.
When editing is requested, we allocate a duplicate copy of the current
block's data to perform edits in. Currently, editing is only supported from
within the hex view, and when edit mode is enabled, the view is locked to
8-bit hex mode in order to avoid any possible confusion with regards to
source vs target endian orientation.
- Extend Draw() to determine whether to write data from the edit data store
or the actual memory block. Also implement highlighting the current edit
position caret when in edit mode, as well as highlighting bytes that have
been changed compared to the block's original data.

03796a0cefd2: Debugger: Add Inspector UI controls for edit mode.

InspectorWindow:
- Add buttons to control edit mode, and helper functions to maintain
their state.
- Implement listener hook for memory change events, to track when
requested memory writes are completed, and update the view accordingly.

Together with the previous batch of commits, this implements the first part
of #9708.

[ Rene Gollent <rene@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

14 files changed, 657 insertions(+), 38 deletions(-)
src/apps/debugger/Jamfile | 1 +
src/apps/debugger/MessageCodes.h | 4 +-
src/apps/debugger/controllers/TeamDebugger.cpp | 52 +++-
src/apps/debugger/controllers/TeamDebugger.h | 7 +-
.../debugger_interface/DebuggerInterface.cpp | 2 +-
src/apps/debugger/jobs/Jobs.h | 24 +-
src/apps/debugger/jobs/WriteMemoryJob.cpp | 50 ++++
src/apps/debugger/model/Team.cpp | 32 ++-
src/apps/debugger/model/Team.h | 27 ++-
src/apps/debugger/user_interface/UserInterface.h | 4 +
.../gui/inspector_window/InspectorWindow.cpp | 188 ++++++++++++++-
.../gui/inspector_window/InspectorWindow.h | 22 +-
.../gui/inspector_window/MemoryView.cpp | 240 +++++++++++++++++--
.../gui/inspector_window/MemoryView.h | 42 +++-

############################################################################

Commit: 40d8306053e09c7221f8d73643761d75fc04c74e
URL: http://cgit.haiku-os.org/haiku/commit/?id=40d8306053e0
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Mon May 4 02:39:13 2015 UTC

Debugger: Fix inverted error check.

InspectorWindow:
- Fix inverted error check when retrieving settings. This was
causing us to fail to successfully load/apply previously stored
settings for the inspector.

----------------------------------------------------------------------------

diff --git
a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
index 0b9569b..1bb6838 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
+++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2014, Rene Gollent, rene@xxxxxxxxxxx. All rights reserved.
+ * Copyright 2011-2015, Rene Gollent, rene@xxxxxxxxxxx. All rights reserved.
* Distributed under the terms of the MIT License.
*/

@@ -409,7 +409,7 @@ InspectorWindow::LoadSettings(const GuiTeamUiSettings&
settings)
return B_ERROR;

BMessage inspectorSettings;
- if (settings.Settings("inspectorWindow", inspectorSettings) == B_OK)
+ if (settings.Settings("inspectorWindow", inspectorSettings) != B_OK)
return B_OK;

BRect frameRect;

############################################################################

Commit: 82bf490fa6a495a264066d1258dd059138b7483d
URL: http://cgit.haiku-os.org/haiku/commit/?id=82bf490fa6a4
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Wed May 13 01:39:22 2015 UTC

Debugger: Fix MemoryView layout issues.

MemoryView:
- Implement {Min,Max,Preferred}Size() hooks. The default BView
versions were causing the inspector to sometimes not be properly
resizable after previous settings were restored.

----------------------------------------------------------------------------

diff --git
a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp
b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp
index bfdd848..5baefb7 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp
+++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2014, Rene Gollent, rene@xxxxxxxxxxx. All rights reserved.
+ * Copyright 2011-2015, Rene Gollent, rene@xxxxxxxxxxx. All rights reserved.
* Distributed under the terms of the MIT License.
*/

@@ -521,6 +521,27 @@ MemoryView::TargetedByScrollView(BScrollView* scrollView)
}


+BSize
+MemoryView::MinSize()
+{
+ return BSize(0.0, 0.0);
+}
+
+
+BSize
+MemoryView::PreferredSize()
+{
+ return MinSize();
+}
+
+
+BSize
+MemoryView::MaxSize()
+{
+ return BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED);
+}
+
+
void
MemoryView::_Init()
{
diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
index 9731971..7b9e576 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
+++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2013, Rene Gollent, rene@xxxxxxxxxxx. All rights reserved.
+ * Copyright 2011-2015, Rene Gollent, rene@xxxxxxxxxxx. All rights reserved.
* Distributed under the terms of the MIT License.
*/

@@ -72,6 +72,11 @@ public:
void ScrollToSelection();
virtual void
TargetedByScrollView(BScrollView* scrollView);

+
+ virtual BSize MinSize();
+ virtual BSize PreferredSize();
+ virtual BSize MaxSize();
+
private:
void _Init();
void _RecalcScrollBars();

############################################################################

Commit: 5474c672709cc0fa65443dea8a35d95ad13c8a98
URL: http://cgit.haiku-os.org/haiku/commit/?id=5474c672709c
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Mon May 4 02:46:00 2015 UTC

Debugger: Add page protection indicator to inspector.

InspectorWindow:
- We now display a label indicating if the currently inspected block
is writable or not, so the user knows whether it's possible to modify
the contents.

----------------------------------------------------------------------------

diff --git
a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
index 1bb6838..d3d0d68 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
+++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
@@ -14,6 +14,7 @@
#include <ControlLook.h>
#include <LayoutBuilder.h>
#include <ScrollView.h>
+#include <StringView.h>
#include <TextControl.h>

#include "Architecture.h"
@@ -37,11 +38,12 @@ InspectorWindow::InspectorWindow(::Team* team,
UserInterfaceListener* listener,
BHandler* target)
:
BWindow(BRect(100, 100, 700, 500), "Inspector", B_TITLED_WINDOW,
- B_ASYNCHRONOUS_CONTROLS),
+ B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
fListener(listener),
fAddressInput(NULL),
fHexMode(NULL),
fTextMode(NULL),
+ fWritableBlockIndicator(NULL),
fMemoryView(NULL),
fCurrentBlock(NULL),
fCurrentAddress(0LL),
@@ -163,6 +165,11 @@ InspectorWindow::_Init()
.End()
.Add(scrollView = new BScrollView("memory scroll",
NULL, 0, false, true), 3.0f)
+ .AddGroup(B_HORIZONTAL)
+ .Add(fWritableBlockIndicator = new
BStringView("writableIndicator",
+ _GetCurrentWritableIndicator()))
+ .AddGlue()
+ .End()
.End();

fHexMode->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
@@ -514,4 +521,23 @@ InspectorWindow::_SetCurrentBlock(TeamMemoryBlock* block)

fCurrentBlock = block;
fMemoryView->SetTargetAddress(fCurrentBlock, fCurrentAddress);
+ _UpdateWritableIndicator();
+}
+
+
+void
+InspectorWindow::_UpdateWritableIndicator()
+{
+ fWritableBlockIndicator->SetText(_GetCurrentWritableIndicator());
+}
+
+
+const char*
+InspectorWindow::_GetCurrentWritableIndicator() const
+{
+ static char buffer[32];
+ snprintf(buffer, sizeof(buffer), "Writable: %s", fCurrentBlock == NULL
+ ? "N/A" : fCurrentBlock->IsWritable() ? "Yes" : "No");
+
+ return buffer;
}
diff --git
a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
index 039e087..0c32013 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
+++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2014, Rene Gollent, rene@xxxxxxxxxxx. All rights reserved.
+ * Copyright 2011-2015, Rene Gollent, rene@xxxxxxxxxxx. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef INSPECTOR_WINDOW_H
@@ -18,6 +18,7 @@
class BButton;
class BMenuField;
class BMessenger;
+class BStringView;
class BTextControl;
class GuiTeamUiSettings;
class SourceLanguage;
@@ -75,12 +76,16 @@ private:
void
_SetToAddress(target_addr_t address);
void
_SetCurrentBlock(TeamMemoryBlock* block);

+ void
_UpdateWritableIndicator();
+ const char*
_GetCurrentWritableIndicator() const;
+
private:
UserInterfaceListener* fListener;
BTextControl* fAddressInput;
BMenuField* fHexMode;
BMenuField* fEndianMode;
BMenuField* fTextMode;
+ BStringView* fWritableBlockIndicator;
MemoryView* fMemoryView;
BButton* fPreviousBlockButton;
BButton* fNextBlockButton;

############################################################################

Commit: 68e78ff84182e9cf9f05dc7ab334ab1cb4e15b80
URL: http://cgit.haiku-os.org/haiku/commit/?id=68e78ff84182
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Sat May 23 20:12:43 2015 UTC

Debugger: Add memory write support.

- Implements various support classes and functions that will be
needed in order to marshal requests to write to memory in the
target team.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile
index d344ee3..ed1ea0f 100644
--- a/src/apps/debugger/Jamfile
+++ b/src/apps/debugger/Jamfile
@@ -162,6 +162,7 @@ Application Debugger :
LoadSourceCodeJob.cpp
ResolveValueNodeJob.cpp
RetrieveMemoryBlockJob.cpp
+ WriteMemoryJob.cpp

# model
AreaInfo.cpp
diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h
index 648e854..fdd0e6d 100644
--- a/src/apps/debugger/MessageCodes.h
+++ b/src/apps/debugger/MessageCodes.h
@@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2013-2015, Rene Gollent, rene@xxxxxxxxxxx.
* Distributed under the terms of the MIT License.
*/
#ifndef MESSAGE_CODES_H
@@ -41,6 +41,7 @@ enum {
MSG_FUNCTION_SOURCE_CODE_CHANGED = 'fnsc',
MSG_USER_BREAKPOINT_CHANGED =
'ubrc',
MSG_WATCHPOINT_CHANGED =
'wapc',
+ MSG_MEMORY_DATA_CHANGED =
'mdac',
MSG_DEBUGGER_EVENT
= 'dbge',
MSG_LOAD_SETTINGS
= 'ldst',

@@ -77,6 +78,7 @@ enum {
MSG_ADD_NEW_EXPRESSION =
'anex',
MSG_EXPRESSION_PROMPT_WINDOW_CLOSED = 'epwc',
MSG_INSPECT_ADDRESS
= 'isad',
+ MSG_WRITE_TARGET_MEMORY =
'wtam',
MSG_EVALUATE_EXPRESSION =
'evex',
MSG_EXPRESSION_EVALUATED =
'exev',
MSG_SHOW_TYPECAST_NODE_PROMPT = 'stnp',
diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp
b/src/apps/debugger/controllers/TeamDebugger.cpp
index 622ed90..9f109a2 100644
--- a/src/apps/debugger/controllers/TeamDebugger.cpp
+++ b/src/apps/debugger/controllers/TeamDebugger.cpp
@@ -1,6 +1,6 @@
/*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2010-2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2010-2015, Rene Gollent, rene@xxxxxxxxxxx.
* Distributed under the terms of the MIT License.
*/

@@ -743,6 +743,24 @@ TeamDebugger::MessageReceived(BMessage* message)
break;
}

+ case MSG_WRITE_TARGET_MEMORY:
+ {
+ target_addr_t address;
+ if (message->FindUInt64("address", &address) != B_OK)
+ break;
+
+ void* data;
+ if (message->FindPointer("data", &data) != B_OK)
+ break;
+
+ target_size_t size;
+ if (message->FindUInt64("size", &size) != B_OK)
+ break;
+
+ _HandleWriteMemory(address, data, size);
+ break;
+ }
+
case MSG_EVALUATE_EXPRESSION:
{
SourceLanguage* language;
@@ -1159,6 +1177,18 @@ TeamDebugger::InspectRequested(target_addr_t address,


void
+TeamDebugger::MemoryWriteRequested(target_addr_t address, const void* data,
+ target_size_t size)
+{
+ BMessage message(MSG_WRITE_TARGET_MEMORY);
+ message.AddUInt64("address", address);
+ message.AddPointer("data", data);
+ message.AddUInt64("size", size);
+ PostMessage(&message);
+}
+
+
+void
TeamDebugger::ExpressionEvaluationRequested(SourceLanguage* language,
ExpressionInfo* info, StackFrame* frame, ::Thread* thread)
{
@@ -2058,6 +2088,26 @@ TeamDebugger::_HandleInspectAddress(target_addr_t
address,


void
+TeamDebugger::_HandleWriteMemory(target_addr_t address, void* data,
+ target_size_t size)
+{
+ TRACE_CONTROL("TeamDebugger::_HandleWriteTargetMemory(%" B_PRIx64 ",
%p, "
+ "%" B_PRIu64 ")\n", address, data, size);
+
+ AutoLocker< ::Team> teamLocker(fTeam);
+ TeamMemory* memory = fTeam->GetTeamMemory();
+ // schedule the job
+ status_t result;
+ if ((result = fWorker->ScheduleJob(
+ new(std::nothrow) WriteMemoryJob(fTeam, memory, address, data,
size),
+ this)) != B_OK) {
+ _NotifyUser("Write Memory", "Failed to write memory data: %s",
+ strerror(result));
+ }
+}
+
+
+void
TeamDebugger::_HandleEvaluateExpression(SourceLanguage* language,
ExpressionInfo* info, StackFrame* frame, ::Thread* thread)
{
diff --git a/src/apps/debugger/controllers/TeamDebugger.h
b/src/apps/debugger/controllers/TeamDebugger.h
index 9b26c36..59d8e94 100644
--- a/src/apps/debugger/controllers/TeamDebugger.h
+++ b/src/apps/debugger/controllers/TeamDebugger.h
@@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2013-2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2013-2015, Rene Gollent, rene@xxxxxxxxxxx.
* Distributed under the terms of the MIT License.
*/
#ifndef TEAM_DEBUGGER_H
@@ -107,6 +107,8 @@ private:

virtual void InspectRequested(target_addr_t
address,

TeamMemoryBlock::Listener* listener);
+ virtual void
MemoryWriteRequested(target_addr_t address,
+ const
void* data, target_size_t size);

virtual void ExpressionEvaluationRequested(

SourceLanguage* language,
@@ -194,6 +196,9 @@ private:
void _HandleInspectAddress(

target_addr_t address,

TeamMemoryBlock::Listener* listener);
+ void _HandleWriteMemory(
+
target_addr_t address, void* data,
+
target_size_t size);

void
_HandleEvaluateExpression(

SourceLanguage* language,
diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp
b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp
index 79eb665..3f78fb4 100644
--- a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp
+++ b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp
@@ -725,7 +725,7 @@ DebuggerInterface::WriteMemory(target_addr_t address, void*
buffer,
DebugContextGetter contextGetter(fDebugContextPool);

return debug_write_memory(contextGetter.Context(),
- (const void*)(addr_t)address, buffer, size);
+ (const void*)address, buffer, size);
}


diff --git a/src/apps/debugger/jobs/Jobs.h b/src/apps/debugger/jobs/Jobs.h
index 65a0ab0..9841fd5 100644
--- a/src/apps/debugger/jobs/Jobs.h
+++ b/src/apps/debugger/jobs/Jobs.h
@@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2011-2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2011-2015, Rene Gollent, rene@xxxxxxxxxxx.
* Distributed under the terms of the MIT License.
*/
#ifndef JOBS_H
@@ -52,6 +52,7 @@ enum {
JOB_TYPE_GET_STACK_FRAME_VALUE,
JOB_TYPE_RESOLVE_VALUE_NODE_VALUE,
JOB_TYPE_GET_MEMORY_BLOCK,
+ JOB_TYPE_WRITE_MEMORY,
JOB_TYPE_EVALUATE_EXPRESSION
};

@@ -233,6 +234,27 @@ private:
};


+class WriteMemoryJob : public Job {
+public:
+
WriteMemoryJob(Team* team,
+
TeamMemory* teamMemory,
+
target_addr_t address, void* data,
+
target_size_t size);
+ virtual ~WriteMemoryJob();
+
+ virtual const JobKey& Key() const;
+ virtual status_t Do();
+
+private:
+ SimpleJobKey fKey;
+ Team* fTeam;
+ TeamMemory* fTeamMemory;
+ target_addr_t fTargetAddress;
+ void* fData;
+ target_size_t fSize;
+};
+
+
class ExpressionEvaluationJob : public Job {
public:

ExpressionEvaluationJob(Team* team,
diff --git a/src/apps/debugger/jobs/WriteMemoryJob.cpp
b/src/apps/debugger/jobs/WriteMemoryJob.cpp
new file mode 100644
index 0000000..116b443
--- /dev/null
+++ b/src/apps/debugger/jobs/WriteMemoryJob.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2015, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "Jobs.h"
+
+#include "Team.h"
+#include "TeamMemory.h"
+
+
+WriteMemoryJob::WriteMemoryJob(Team* team,
+ TeamMemory* teamMemory, target_addr_t address, void* data,
+ target_size_t size)
+ :
+ fKey(data, JOB_TYPE_WRITE_MEMORY),
+ fTeam(team),
+ fTeamMemory(teamMemory),
+ fTargetAddress(address),
+ fData(data),
+ fSize(size)
+{
+ fTeamMemory->AcquireReference();
+}
+
+
+WriteMemoryJob::~WriteMemoryJob()
+{
+ fTeamMemory->ReleaseReference();
+}
+
+
+const JobKey&
+WriteMemoryJob::Key() const
+{
+ return fKey;
+}
+
+
+status_t
+WriteMemoryJob::Do()
+{
+ ssize_t result = fTeamMemory->WriteMemory(fTargetAddress, fData, fSize);
+ if (result < 0)
+ return result;
+
+ fTeam->NotifyMemoryChanged(fTargetAddress, fSize);
+
+ return B_OK;
+}
diff --git a/src/apps/debugger/model/Team.cpp b/src/apps/debugger/model/Team.cpp
index ca90e71..d915a82 100644
--- a/src/apps/debugger/model/Team.cpp
+++ b/src/apps/debugger/model/Team.cpp
@@ -1,6 +1,6 @@
/*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2013-2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2013-2015, Rene Gollent, rene@xxxxxxxxxxx.
* Distributed under the terms of the MIT License.
*/

@@ -733,6 +733,17 @@ Team::NotifyDebugReportChanged(const char* reportPath)


void
+Team::NotifyMemoryChanged(target_addr_t address, target_size_t size)
+{
+ for (ListenerList::Iterator it = fListeners.GetIterator();
+ Listener* listener = it.Next();) {
+ listener->MemoryChanged(MemoryChangedEvent(
+ TEAM_EVENT_MEMORY_CHANGED, this, address, size));
+ }
+}
+
+
+void
Team::_NotifyThreadAdded(Thread* thread)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
@@ -867,6 +878,19 @@ Team::DebugReportEvent::DebugReportEvent(uint32 type,
Team* team,
}


+// #pragma mark - MemoryChangedEvent
+
+
+Team::MemoryChangedEvent::MemoryChangedEvent(uint32 type, Team* team,
+ target_addr_t address, target_size_t size)
+ :
+ Event(type, team),
+ fTargetAddress(address),
+ fSize(size)
+{
+}
+
+
// #pragma mark - WatchpointEvent


@@ -1013,3 +1037,9 @@ void
Team::Listener::DebugReportChanged(const Team::DebugReportEvent& event)
{
}
+
+
+void
+Team::Listener::MemoryChanged(const Team::MemoryChangedEvent& event)
+{
+}
diff --git a/src/apps/debugger/model/Team.h b/src/apps/debugger/model/Team.h
index 685dad2..243fec0 100644
--- a/src/apps/debugger/model/Team.h
+++ b/src/apps/debugger/model/Team.h
@@ -48,7 +48,9 @@ enum {
TEAM_EVENT_WATCHPOINT_REMOVED,
TEAM_EVENT_WATCHPOINT_CHANGED,

- TEAM_EVENT_DEBUG_REPORT_CHANGED
+ TEAM_EVENT_DEBUG_REPORT_CHANGED,
+
+ TEAM_EVENT_MEMORY_CHANGED
};


@@ -75,6 +77,7 @@ public:
class BreakpointEvent;
class ConsoleOutputEvent;
class DebugReportEvent;
+ class MemoryChangedEvent;
class ImageEvent;
class ImageLoadEvent;
class ImageLoadNameEvent;
@@ -225,6 +228,10 @@ public:
void
NotifyDebugReportChanged(
const
char* reportPath);

+ // memory write related service methods
+ void
NotifyMemoryChanged(target_addr_t address,
+
target_size_t size);
+
private:
struct BreakpointByAddressPredicate;
struct WatchpointByAddressPredicate;
@@ -360,6 +367,21 @@ protected:
};


+class Team::MemoryChangedEvent : public Event {
+public:
+
MemoryChangedEvent(uint32 type, Team* team,
+
target_addr_t address, target_size_t size);
+
+ target_addr_t GetTargetAddress() const
+ {
return fTargetAddress; }
+
+ target_size_t GetSize() const { return fSize;
}
+protected:
+ target_addr_t fTargetAddress;
+ target_size_t fSize;
+};
+
+
class Team::WatchpointEvent : public Event {
public:

WatchpointEvent(uint32 type, Team* team,
@@ -430,6 +452,9 @@ public:

virtual void DebugReportChanged(
const
Team::DebugReportEvent& event);
+
+ virtual void MemoryChanged(
+ const
Team::MemoryChangedEvent& event);
};


diff --git a/src/apps/debugger/user_interface/UserInterface.h
b/src/apps/debugger/user_interface/UserInterface.h
index 92f7191..d95a09f 100644
--- a/src/apps/debugger/user_interface/UserInterface.h
+++ b/src/apps/debugger/user_interface/UserInterface.h
@@ -142,6 +142,10 @@ public:
virtual void InspectRequested(

target_addr_t address,

TeamMemoryBlock::Listener* listener) = 0;
+ virtual void MemoryWriteRequested(
+
target_addr_t address,
+ const
void* data,
+
target_size_t length) = 0;

virtual void ExpressionEvaluationRequested(

SourceLanguage* language,

############################################################################

Commit: 76ada671ba3b389dcf1bdf22c140130572e14731
URL: http://cgit.haiku-os.org/haiku/commit/?id=76ada671ba3b
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Fri May 22 22:01:07 2015 UTC

Debugger: Extend MemoryView listener interface.

MemoryView::Listener:
- Add extra hooks for notifying listener of internal mode changes.
Implement accordingly in InspectorWindow.

----------------------------------------------------------------------------

diff --git
a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
index d3d0d68..51bcae9 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
+++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
@@ -392,6 +392,48 @@ InspectorWindow::TargetAddressChanged(target_addr_t
address)


void
+InspectorWindow::HexModeChanged(int32 newMode)
+{
+ AutoLocker<BLooper> lock(this);
+ if (lock.IsLocked()) {
+ BMenu* menu = fHexMode->Menu();
+ if (newMode < 0 || newMode > menu->CountItems())
+ return;
+ BMenuItem* item = menu->ItemAt(newMode);
+ item->SetMarked(true);
+ }
+}
+
+
+void
+InspectorWindow::EndianModeChanged(int32 newMode)
+{
+ AutoLocker<BLooper> lock(this);
+ if (lock.IsLocked()) {
+ BMenu* menu = fEndianMode->Menu();
+ if (newMode < 0 || newMode > menu->CountItems())
+ return;
+ BMenuItem* item = menu->ItemAt(newMode);
+ item->SetMarked(true);
+ }
+}
+
+
+void
+InspectorWindow::TextModeChanged(int32 newMode)
+{
+ AutoLocker<BLooper> lock(this);
+ if (lock.IsLocked()) {
+ BMenu* menu = fTextMode->Menu();
+ if (newMode < 0 || newMode > menu->CountItems())
+ return;
+ BMenuItem* item = menu->ItemAt(newMode);
+ item->SetMarked(true);
+ }
+}
+
+
+void
InspectorWindow::ExpressionEvaluated(ExpressionInfo* info, status_t result,
ExpressionResult* value)
{
diff --git
a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
index 0c32013..79265a1 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
+++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
@@ -53,6 +53,9 @@ public:

// MemoryView::Listener
virtual void
TargetAddressChanged(target_addr_t address);
+ virtual void HexModeChanged(int32 newMode);
+ virtual void EndianModeChanged(int32
newMode);
+ virtual void TextModeChanged(int32 newMode);

// ExpressionInfo::Listener
virtual void
ExpressionEvaluated(ExpressionInfo* info,
diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
index 7b9e576..0df94fd 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
+++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
@@ -132,6 +132,10 @@ public:

virtual void
TargetAddressChanged(target_addr_t address)
= 0;
+
+ virtual void HexModeChanged(int32 newMode) =
0;
+ virtual void TextModeChanged(int32 newMode)
= 0;
+ virtual void EndianModeChanged(int32
newMode) = 0;
};



############################################################################

Commit: 6ce909030dbe3ccb518741d18ebe162475f1a052
URL: http://cgit.haiku-os.org/haiku/commit/?id=6ce909030dbe
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Sun May 17 20:54:52 2015 UTC

Debugger: Add edit mode support to MemoryView.

MemoryView:
- Add hooks and supporting status tracking members to enable edit mode.
When editing is requested, we allocate a duplicate copy of the current
block's data to perform edits in. Currently, editing is only supported from
within the hex view, and when edit mode is enabled, the view is locked to
8-bit hex mode in order to avoid any possible confusion with regards to
source vs target endian orientation.
- Extend Draw() to determine whether to write data from the edit data store
or the actual memory block. Also implement highlighting the current edit
position caret when in edit mode, as well as highlighting bytes that have
been changed compared to the block's original data.

----------------------------------------------------------------------------

diff --git
a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp
b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp
index 5baefb7..59d484a 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp
+++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp
@@ -8,6 +8,7 @@

#include <algorithm>

+#include <ctype.h>
#include <stdio.h>

#include <ByteOrder.h>
@@ -29,7 +30,7 @@


enum {
- MSG_TARGET_ADDRESS_CHANGED = 'mtac',
+ MSG_TARGET_ADDRESS_CHANGED = 'mtac',
MSG_VIEW_AUTOSCROLL = 'mvas'
};

@@ -42,7 +43,11 @@ MemoryView::MemoryView(::Team* team, Listener* listener)
| B_SUBPIXEL_PRECISE),
fTeam(team),
fTargetBlock(NULL),
+ fEditableData(NULL),
+ fEditedOffsets(),
fTargetAddress(0LL),
+ fEditMode(false),
+ fEditLowNybble(false),
fCharWidth(0.0),
fLineHeight(0.0),
fTextCharsPerLine(0),
@@ -67,6 +72,8 @@ MemoryView::~MemoryView()
{
if (fTargetBlock != NULL)
fTargetBlock->ReleaseReference();
+
+ delete[] fEditableData;
}


@@ -111,6 +118,32 @@ MemoryView::UnsetListener()
}


+status_t
+MemoryView::SetEditMode(bool enabled)
+{
+ if (fTargetBlock == NULL)
+ return B_BAD_VALUE;
+ else if (fEditMode == enabled)
+ return B_OK;
+
+ if (enabled) {
+ status_t error = _SetupEditableData();
+ if (error != B_OK)
+ return error;
+ } else {
+ delete[] fEditableData;
+ fEditableData = NULL;
+ fEditedOffsets.clear();
+ fEditLowNybble = false;
+ }
+
+ fEditMode = enabled;
+ Invalidate();
+
+ return B_OK;
+}
+
+
void
MemoryView::AttachedToWindow()
{
@@ -148,13 +181,15 @@ MemoryView::Draw(BRect rect)
char buffer[32];
char textbuffer[512];

+ const char* dataSource = (const char*)(fEditMode ? fEditableData
+ : fTargetBlock->Data());
+
int32 startLine = int32(rect.top / fLineHeight);
- const char* currentAddress = (const char*)(fTargetBlock->Data()
- + fHexBlocksPerLine * blockByteSize * startLine);
- const char* maxAddress = (const char*)(fTargetBlock->Data()
- + fTargetBlock->Size());
- const char* targetAddress = (const char *)fTargetBlock->Data()
- + fTargetAddress - fTargetBlock->BaseAddress();
+ const char* currentAddress = dataSource + fHexBlocksPerLine
+ * blockByteSize * startLine;
+ const char* maxAddress = dataSource + fTargetBlock->Size();
+ const char* targetAddress = dataSource + fTargetAddress
+ - fTargetBlock->BaseAddress();
BPoint drawPoint(1.0, (startLine + 1) * fLineHeight);
int32 currentBlocksPerLine = fHexBlocksPerLine;
int32 currentCharsPerLine = fTextCharsPerLine;
@@ -164,6 +199,8 @@ MemoryView::Draw(BRect rect)
GetFontHeight(&fh);
target_addr_t lineAddress = fTargetBlock->BaseAddress() + startLine
* currentCharsPerLine;
+ bool highlightBlock = false;
+ rgb_color highlightColor;
for (; currentAddress < maxAddress && drawPoint.y < rect.bottom
+ fLineHeight; drawPoint.y += fLineHeight) {
drawPoint.x = 1.0;
@@ -186,14 +223,34 @@ MemoryView::Draw(BRect rect)
const char* blockAddress = currentAddress + (j
* blockByteSize);
_GetNextHexBlock(buffer, sizeof(buffer),
blockAddress);
- if (targetAddress >= blockAddress &&
targetAddress <
+
+ highlightBlock = false;
+ if (fEditMode)
+ {
+ int32 offset = blockAddress -
dataSource;
+ for (uint32 i = 0; i < blockByteSize;
i++) {
+ if (fEditedOffsets.count(offset
+ i) != 0) {
+ highlightBlock = true;
+
highlightColor.set_to(0, 216, 0);
+ break;
+ }
+ }
+
+ } else if (targetAddress >= blockAddress &&
targetAddress <
blockAddress + blockByteSize) {
+ highlightBlock = true;
+ highlightColor.set_to(216, 0,
0);
+ }
+
+ if (highlightBlock) {
PushState();
- SetHighColor(make_color(216,0,0));
- DrawString(buffer, drawPoint);
+ SetHighColor(highlightColor);
+ }
+
+ DrawString(buffer, drawPoint);
+
+ if (highlightBlock)
PopState();
- } else
- DrawString(buffer, drawPoint);

drawPoint.x += fCharWidth * hexBlockSize;
}
@@ -248,6 +305,16 @@ MemoryView::Draw(BRect rect)
FillRegion(&selectionRegion, B_SOLID_HIGH);
PopState();
}
+
+ if (fEditMode) {
+ PushState();
+ BRect caretRect;
+ _GetEditCaretRect(caretRect);
+ SetDrawingMode(B_OP_INVERT);
+ FillRect(caretRect, B_SOLID_HIGH);
+ PopState();
+
+ }
}


@@ -286,12 +353,22 @@ MemoryView::KeyDown(const char* bytes, int32 numBytes)
}
case B_LEFT_ARROW:
{
- newAddress -= blockSize;
+ if (fEditMode) {
+ if (!fEditLowNybble)
+ newAddress--;
+ fEditLowNybble = !fEditLowNybble;
+ } else
+ newAddress -= blockSize;
break;
}
case B_RIGHT_ARROW:
{
- newAddress += blockSize;
+ if (fEditMode) {
+ if (fEditLowNybble)
+ newAddress++;
+ fEditLowNybble = !fEditLowNybble;
+ } else
+ newAddress += blockSize;
break;
}
case B_PAGE_UP:
@@ -307,19 +384,59 @@ MemoryView::KeyDown(const char* bytes, int32 numBytes)
case B_HOME:
{
newAddress = fTargetBlock->BaseAddress();
+ fEditLowNybble = false;
break;
}
case B_END:
{
newAddress = maxAddress;
+ fEditLowNybble = true;
break;
}
default:
{
- handled = false;
+ if (fEditMode && isxdigit(bytes[0]))
+ {
+ int value = 0;
+ if (isdigit(bytes[0]))
+ value = bytes[0] - '0';
+ else
+ value = (int)strtol(bytes,
NULL, 16);
+
+ int32 byteOffset = fTargetAddress
+ - fTargetBlock->BaseAddress();
+
+ if (fEditLowNybble)
+ value =
(fEditableData[byteOffset] & 0xf0) | value;
+ else {
+ value =
(fEditableData[byteOffset] & 0x0f)
+ | (value << 4);
+ }
+
+ fEditableData[byteOffset] = value;
+
+ if (fEditableData[byteOffset]
+ !=
fTargetBlock->Data()[byteOffset]) {
+
fEditedOffsets.insert(byteOffset);
+ } else
+
fEditedOffsets.erase(byteOffset);
+
+ if (fEditLowNybble) {
+ if (newAddress < maxAddress) {
+ newAddress++;
+ fEditLowNybble = false;
+ }
+ } else
+ fEditLowNybble = true;
+
+ Invalidate();
+ } else
+ handled = false;
+
break;
}
}
+
if (handled) {
if (newAddress < fTargetBlock->BaseAddress())
newAddress = fTargetAddress;
@@ -370,11 +487,21 @@ MemoryView::MessageReceived(BMessage* message)
}
case MSG_SET_HEX_MODE:
{
+ // while editing, hex view changes are disallowed.
+ if (fEditMode)
+ break;
+
int32 mode;
if (message->FindInt32("mode", &mode) == B_OK) {
+ if (fHexMode == mode)
+ break;
+
fHexMode = mode;
_RecalcScrollBars();
Invalidate();
+
+ if (fListener != NULL)
+ fListener->HexModeChanged(mode);
}
break;
}
@@ -382,8 +509,14 @@ MemoryView::MessageReceived(BMessage* message)
{
int32 mode;
if (message->FindInt32("mode", &mode) == B_OK) {
+ if (fCurrentEndianMode == mode)
+ break;
+
fCurrentEndianMode = mode;
Invalidate();
+
+ if (fListener != NULL)
+ fListener->EndianModeChanged(mode);
}
break;
}
@@ -391,9 +524,15 @@ MemoryView::MessageReceived(BMessage* message)
{
int32 mode;
if (message->FindInt32("mode", &mode) == B_OK) {
+ if (fTextMode == mode)
+ break;
+
fTextMode = mode;
_RecalcScrollBars();
Invalidate();
+
+ if (fListener != NULL)
+ fListener->TextModeChanged(mode);
}
break;
}
@@ -593,7 +732,7 @@ MemoryView::_RecalcScrollBars()

void
MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize,
- const char* address)
+ const char* address) const
{
switch(fHexMode) {
case HexMode8BitInt:
@@ -765,7 +904,25 @@ MemoryView::_GetAddressDisplayWidth() const


void
-MemoryView::_GetSelectionRegion(BRegion& region)
+MemoryView::_GetEditCaretRect(BRect& rect) const
+{
+ if (!fEditMode)
+ return;
+
+ int32 byteOffset = fTargetAddress - fTargetBlock->BaseAddress();
+ BPoint point = _GetPointForOffset(byteOffset);
+ if (fEditLowNybble)
+ point.x += fCharWidth;
+
+ rect.left = point.x;
+ rect.right = point.x + fCharWidth;
+ rect.top = point.y;
+ rect.bottom = point.y + fLineHeight;
+}
+
+
+void
+MemoryView::_GetSelectionRegion(BRegion& region) const
{
if (fHexMode == HexModeNone || fTargetBlock == NULL)
return;
@@ -812,14 +969,15 @@ MemoryView::_GetSelectionRegion(BRegion& region)


void
-MemoryView::_GetSelectedText(BString& text)
+MemoryView::_GetSelectedText(BString& text) const
{
if (fSelectionStart == fSelectionEnd)
return;

text.Truncate(0);
+ const uint8* dataSource = fEditMode ? fEditableData :
fTargetBlock->Data();

- char* data = (char *)fTargetBlock->Data() + fSelectionStart;
+ const char* data = (const char *)dataSource + fSelectionStart;
int16 blockSize = _GetHexDigitsPerBlock() / 2;
int32 count = (fSelectionEnd - fSelectionStart)
/ blockSize;
@@ -959,6 +1117,27 @@ MemoryView::_HandleContextMenu(BPoint point)
}


+status_t
+MemoryView::_SetupEditableData()
+{
+ fEditableData = new(std::nothrow) uint8[fTargetBlock->Size()];
+ if (fEditableData == NULL)
+ return B_NO_MEMORY;
+
+ memcpy(fEditableData, fTargetBlock->Data(), fTargetBlock->Size());
+
+ if (fHexMode != HexMode8BitInt) {
+ fHexMode = HexMode8BitInt;
+ if (fListener != NULL)
+ fListener->HexModeChanged(fHexMode);
+
+ _RecalcScrollBars();
+ }
+
+ return B_OK;
+}
+
+
//#pragma mark - Listener


diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
index 0df94fd..91f6c7a 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
+++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h
@@ -7,6 +7,8 @@
#define MEMORY_VIEW_H


+#include <set>
+
#include <View.h>

#include "Types.h"
@@ -24,7 +26,6 @@ enum {
HexMode16BitInt,
HexMode32BitInt,
HexMode64BitInt
- // TODO: floating point representation?
};

enum {
@@ -56,9 +57,18 @@ public:

void
SetTargetAddress(TeamMemoryBlock* block,

target_addr_t address);
-
void UnsetListener();

+ inline bool GetEditMode() const
+ {
return fEditMode; }
+ status_t SetEditMode(bool
enabled);
+
+ inline void* GetEditedData() const
+ {
return fEditableData; }
+
+ void CommitChanges();
+ void RevertChanges();
+
virtual void AttachedToWindow();
virtual void Draw(BRect rect);
virtual void FrameResized(float width, float
height);
@@ -81,7 +91,8 @@ private:
void _Init();
void _RecalcScrollBars();
void _GetNextHexBlock(char*
buffer,
- int32
bufferSize, const char* address);
+ int32
bufferSize,
+ const
char* address) const;

int32 _GetOffsetAt(BPoint
point) const;
BPoint
_GetPointForOffset(int32 offset) const;
@@ -91,18 +102,28 @@ private:
inline int32 _GetHexDigitsPerBlock() const
{
return 1 << fHexMode; };

- void
_GetSelectionRegion(BRegion& region);
- void
_GetSelectedText(BString& text);
+ void
_GetEditCaretRect(BRect& rect) const;
+ void
_GetSelectionRegion(BRegion& region) const;
+ void
_GetSelectedText(BString& text) const;
void
_CopySelectionToClipboard();

void _HandleAutoScroll();
void _ScrollByLines(int32
lineCount);
void
_HandleContextMenu(BPoint point);

+ status_t _SetupEditableData();
+
+private:
+ typedef std::set<int32> ModifiedIndexSet;
+
private:
::Team* fTeam;
TeamMemoryBlock* fTargetBlock;
+ uint8* fEditableData;
+ ModifiedIndexSet fEditedOffsets;
target_addr_t fTargetAddress;
+ bool fEditMode;
+ bool fEditLowNybble;
float fCharWidth;
float fLineHeight;
int32 fTargetAddressSize;

############################################################################

Revision: hrev49189
Commit: 03796a0cefd2568ee7c7eb3f0a0164f7f48cc9b1
URL: http://cgit.haiku-os.org/haiku/commit/?id=03796a0cefd2
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Sat May 16 21:35:58 2015 UTC

Ticket: https://dev.haiku-os.org/ticket/9708

Debugger: Add Inspector UI controls for edit mode.

InspectorWindow:
- Add buttons to control edit mode, and helper functions to maintain
their state.
- Implement listener hook for memory change events, to track when
requested memory writes are completed, and update the view accordingly.

Together with the previous batch of commits, this implements the first part
of #9708.

----------------------------------------------------------------------------

diff --git
a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
index 51bcae9..68efbee 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
+++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp
@@ -30,7 +30,10 @@
enum {
MSG_NAVIGATE_PREVIOUS_BLOCK = 'npbl',
MSG_NAVIGATE_NEXT_BLOCK = 'npnl',
- MSG_MEMORY_BLOCK_RETRIEVED = 'mbre'
+ MSG_MEMORY_BLOCK_RETRIEVED = 'mbre',
+ MSG_EDIT_CURRENT_BLOCK = 'mecb',
+ MSG_COMMIT_MODIFIED_BLOCK = 'mcmb',
+ MSG_REVERT_MODIFIED_BLOCK = 'mrmb'
};


@@ -169,6 +172,12 @@ InspectorWindow::_Init()
.Add(fWritableBlockIndicator = new
BStringView("writableIndicator",
_GetCurrentWritableIndicator()))
.AddGlue()
+ .Add(fEditBlockButton = new BButton("editBlock", "Edit",
+ new BMessage(MSG_EDIT_CURRENT_BLOCK)))
+ .Add(fCommitBlockButton = new BButton("commitBlock",
"Commit",
+ new BMessage(MSG_COMMIT_MODIFIED_BLOCK)))
+ .Add(fRevertBlockButton = new BButton("revertBlock",
"Revert",
+ new BMessage(MSG_REVERT_MODIFIED_BLOCK)))
.End()
.End();

@@ -187,6 +196,14 @@ InspectorWindow::_Init()
fPreviousBlockButton->SetEnabled(false);
fNextBlockButton->SetEnabled(false);

+ fEditBlockButton->SetTarget(this);
+ fCommitBlockButton->SetTarget(this);
+ fRevertBlockButton->SetTarget(this);
+
+ fEditBlockButton->SetEnabled(false);
+ fCommitBlockButton->Hide();
+ fRevertBlockButton->Hide();
+
hexMenu->SetLabelFromMarked(true);
hexMenu->SetTargetForItems(fMemoryView);
endianMenu->SetLabelFromMarked(true);
@@ -325,6 +342,43 @@ InspectorWindow::MessageReceived(BMessage* message)
}
break;
}
+ case MSG_EDIT_CURRENT_BLOCK:
+ {
+ _SetEditMode(true);
+ break;
+ }
+ case MSG_MEMORY_DATA_CHANGED:
+ {
+ if (fCurrentBlock == NULL)
+ break;
+
+ target_addr_t address;
+ if (message->FindUInt64("address", &address) == B_OK
+ && address >= fCurrentBlock->BaseAddress()
+ && address < fCurrentBlock->BaseAddress()
+ + fCurrentBlock->Size()) {
+ fCurrentBlock->Invalidate();
+ _SetEditMode(false);
+ fListener->InspectRequested(address, this);
+ }
+ break;
+ }
+ case MSG_COMMIT_MODIFIED_BLOCK:
+ {
+ // TODO: this could conceivably be extended to detect
the
+ // individual modified regions and only write those
back.
+ // That would require potentially submitting multiple
separate
+ // write requests, and thus require tracking all the
writes being
+ // waited upon for completion.
+
fListener->MemoryWriteRequested(fCurrentBlock->BaseAddress(),
+ fMemoryView->GetEditedData(),
fCurrentBlock->Size());
+ break;
+ }
+ case MSG_REVERT_MODIFIED_BLOCK:
+ {
+ _SetEditMode(false);
+ break;
+ }
default:
{
BWindow::MessageReceived(message);
@@ -358,6 +412,17 @@ InspectorWindow::ThreadStateChanged(const
Team::ThreadEvent& event)


void
+InspectorWindow::MemoryChanged(const Team::MemoryChangedEvent& event)
+{
+ BMessage message(MSG_MEMORY_DATA_CHANGED);
+ message.AddUInt64("address", event.GetTargetAddress());
+ message.AddUInt64("size", event.GetSize());
+
+ PostMessage(&message);
+}
+
+
+void
InspectorWindow::MemoryBlockRetrieved(TeamMemoryBlock* block)
{
BMessage message(MSG_MEMORY_BLOCK_RETRIEVED);
@@ -563,6 +628,53 @@ InspectorWindow::_SetCurrentBlock(TeamMemoryBlock* block)

fCurrentBlock = block;
fMemoryView->SetTargetAddress(fCurrentBlock, fCurrentAddress);
+ _UpdateWritableOptions();
+}
+
+
+bool
+InspectorWindow::_GetWritableState() const
+{
+ return fCurrentBlock != NULL ? fCurrentBlock->IsWritable() : false;
+}
+
+
+void
+InspectorWindow::_SetEditMode(bool enabled)
+{
+ if (enabled == fMemoryView->GetEditMode())
+ return;
+
+ status_t error = fMemoryView->SetEditMode(enabled);
+ if (error != B_OK)
+ return;
+
+ if (enabled) {
+ fEditBlockButton->Hide();
+ fCommitBlockButton->Show();
+ fRevertBlockButton->Show();
+ } else {
+ fEditBlockButton->Show();
+ fCommitBlockButton->Hide();
+ fRevertBlockButton->Hide();
+ }
+
+ fHexMode->SetEnabled(!enabled);
+ fEndianMode->SetEnabled(!enabled);
+
+ // while the block is being edited, disable block navigation controls.
+ fAddressInput->SetEnabled(!enabled);
+ fPreviousBlockButton->SetEnabled(!enabled);
+ fNextBlockButton->SetEnabled(!enabled);
+
+ InvalidateLayout();
+}
+
+
+void
+InspectorWindow::_UpdateWritableOptions()
+{
+ fEditBlockButton->SetEnabled(_GetWritableState());
_UpdateWritableIndicator();
}

diff --git
a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
index 79265a1..0dafddb 100644
--- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
+++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h
@@ -46,6 +46,9 @@ public:
virtual void ThreadStateChanged(
const
Team::ThreadEvent& event);

+ virtual void MemoryChanged(
+ const
Team::MemoryChangedEvent& event);
+
// TeamMemoryBlock::Listener
virtual void
MemoryBlockRetrieved(TeamMemoryBlock* block);
virtual void MemoryBlockRetrievalFailed(
@@ -79,6 +82,12 @@ private:
void
_SetToAddress(target_addr_t address);
void
_SetCurrentBlock(TeamMemoryBlock* block);

+ void _SetEditMode(bool
enabled);
+
+ bool _GetWritableState()
const;
+
+ void
_UpdateWritableOptions();
+
void
_UpdateWritableIndicator();
const char*
_GetCurrentWritableIndicator() const;

@@ -92,6 +101,9 @@ private:
MemoryView* fMemoryView;
BButton* fPreviousBlockButton;
BButton* fNextBlockButton;
+ BButton* fEditBlockButton;
+ BButton* fCommitBlockButton;
+ BButton* fRevertBlockButton;
TeamMemoryBlock* fCurrentBlock;
target_addr_t fCurrentAddress;
::Team* fTeam;


Other related posts:

  • » [haiku-commits] haiku: hrev49189 - in src/apps/debugger: user_interface/gui/inspector_window controllers model jobs - anevilyak