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.
This commit is contained in:
Rene Gollent
2015-05-23 16:54:16 -04:00
parent 5474c67270
commit 68e78ff841
10 changed files with 196 additions and 7 deletions
+1
View File
@@ -162,6 +162,7 @@ Application Debugger :
LoadSourceCodeJob.cpp
ResolveValueNodeJob.cpp
RetrieveMemoryBlockJob.cpp
WriteMemoryJob.cpp
# model
AreaInfo.cpp
+3 -1
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Copyright 2013, Rene Gollent, [email protected].
* Copyright 2013-2015, Rene Gollent, [email protected].
* 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',
+51 -1
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2009-2012, Ingo Weinhold, [email protected].
* Copyright 2010-2014, Rene Gollent, [email protected].
* Copyright 2010-2015, Rene Gollent, [email protected].
* 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;
@@ -1158,6 +1176,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)
@@ -2057,6 +2087,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)
+6 -1
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2013-2014, Rene Gollent, rene@gollent.com.
* Copyright 2013-2015, Rene Gollent, rene@gollent.com.
* 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,
@@ -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);
}
+23 -1
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2011-2014, Rene Gollent, rene@gollent.com.
* Copyright 2011-2015, Rene Gollent, rene@gollent.com.
* 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,
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright 2015, Rene Gollent, rene@gollent.com.
* 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;
}
+31 -1
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2013-2014, Rene Gollent, rene@gollent.com.
* Copyright 2013-2015, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
@@ -732,6 +732,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)
{
@@ -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)
{
}
+26 -1
View File
@@ -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);
};
@@ -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,