diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index a8c60b316b..83f10bbcb9 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -162,6 +162,7 @@ local sources = ResolveValueNodeJob.cpp RetrieveMemoryBlockJob.cpp WriteMemoryJob.cpp + WriteValueNodeJob.cpp # model AreaInfo.cpp diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp index 90f445e371..e9d92bbe81 100644 --- a/src/apps/debugger/controllers/TeamDebugger.cpp +++ b/src/apps/debugger/controllers/TeamDebugger.cpp @@ -1035,13 +1035,31 @@ TeamDebugger::ValueNodeValueRequested(CpuState* cpuState, status_t error = fWorker->ScheduleJob( new(std::nothrow) ResolveValueNodeValueJob(fDebuggerInterface, fDebuggerInterface->GetArchitecture(), cpuState, - fTeam->GetTeamTypeInformation(), container, valueNode), this); + fTeam->GetTeamTypeInformation(), container, valueNode), this); if (error != B_OK) { // scheduling failed -- set the value to invalid valueNode->SetLocationAndValue(NULL, NULL, error); } } +void +TeamDebugger::ValueNodeWriteRequested(ValueNode* node, CpuState* state, + Value* newValue) +{ + // schedule the job + status_t error = fWorker->ScheduleJob( + new(std::nothrow) WriteValueNodeValueJob(fDebuggerInterface, + fDebuggerInterface->GetArchitecture(), state, + fTeam->GetTeamTypeInformation(), node, newValue), this); + if (error != B_OK) { + BString message; + message.SetToFormat("Request to write new value for variable %s " + "failed: %s.\n", node->Name().String(), strerror(error)); + fUserInterface->NotifyUser("Error", message.String(), + USER_NOTIFICATION_ERROR); + } +} + void TeamDebugger::ThreadActionRequested(thread_id threadID, diff --git a/src/apps/debugger/controllers/TeamDebugger.h b/src/apps/debugger/controllers/TeamDebugger.h index 377a9ea586..371a0ed3f5 100644 --- a/src/apps/debugger/controllers/TeamDebugger.h +++ b/src/apps/debugger/controllers/TeamDebugger.h @@ -73,6 +73,9 @@ private: virtual void ValueNodeValueRequested(CpuState* cpuState, ValueNodeContainer* container, ValueNode* valueNode); + virtual void ValueNodeWriteRequested(ValueNode* node, + CpuState* state, + Value* newValue); virtual void ThreadActionRequested(thread_id threadID, uint32 action, target_addr_t address); diff --git a/src/apps/debugger/jobs/Jobs.h b/src/apps/debugger/jobs/Jobs.h index 9841fd57b2..1f6b2444ca 100644 --- a/src/apps/debugger/jobs/Jobs.h +++ b/src/apps/debugger/jobs/Jobs.h @@ -51,6 +51,7 @@ enum { JOB_TYPE_LOAD_SOURCE_CODE, JOB_TYPE_GET_STACK_FRAME_VALUE, JOB_TYPE_RESOLVE_VALUE_NODE_VALUE, + JOB_TYPE_WRITE_VALUE_NODE_VALUE, JOB_TYPE_GET_MEMORY_BLOCK, JOB_TYPE_WRITE_MEMORY, JOB_TYPE_EVALUATE_EXPRESSION @@ -216,6 +217,32 @@ private: }; +class WriteValueNodeValueJob : public Job { +public: + WriteValueNodeValueJob( + DebuggerInterface* debuggerInterface, + Architecture* architecture, + CpuState* cpuState, + TeamTypeInformation* typeInformation, + ValueNode* valueNode, + Value* newValue); + virtual ~WriteValueNodeValueJob(); + + virtual const JobKey& Key() const; + virtual status_t Do(); + +private: + SimpleJobKey fKey; + DebuggerInterface* fDebuggerInterface; + Architecture* fArchitecture; + CpuState* fCpuState; + TeamTypeInformation* + fTypeInformation; + ValueNode* fValueNode; + Value* fNewValue; +}; + + class RetrieveMemoryBlockJob : public Job { public: RetrieveMemoryBlockJob(Team* team, diff --git a/src/apps/debugger/jobs/WriteValueNodeJob.cpp b/src/apps/debugger/jobs/WriteValueNodeJob.cpp new file mode 100644 index 0000000000..40c4bf0ab7 --- /dev/null +++ b/src/apps/debugger/jobs/WriteValueNodeJob.cpp @@ -0,0 +1,80 @@ +/* + * Copyright 2015, Rene Gollent, rene@gollent.com. + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include "Jobs.h" + +#include + +#include "Architecture.h" +#include "CpuState.h" +#include "DebuggerInterface.h" +#include "TeamTypeInformation.h" +#include "Tracing.h" +#include "Value.h" +#include "ValueLocation.h" +#include "ValueNode.h" +#include "ValueNodeContainer.h" +#include "ValueWriter.h" + + +WriteValueNodeValueJob::WriteValueNodeValueJob( + DebuggerInterface* debuggerInterface, Architecture* architecture, + CpuState* cpuState, TeamTypeInformation* typeInformation, + ValueNode* valueNode, Value* newValue) + : + fKey(valueNode, JOB_TYPE_WRITE_VALUE_NODE_VALUE), + fDebuggerInterface(debuggerInterface), + fArchitecture(architecture), + fCpuState(cpuState), + fTypeInformation(typeInformation), + fValueNode(valueNode), + fNewValue(newValue) +{ + if (fCpuState != NULL) + fCpuState->AcquireReference(); + fValueNode->AcquireReference(); + fNewValue->AcquireReference(); +} + + +WriteValueNodeValueJob::~WriteValueNodeValueJob() +{ + if (fCpuState != NULL) + fCpuState->ReleaseReference(); + fValueNode->ReleaseReference(); + fNewValue->ReleaseReference(); +} + + +const JobKey& +WriteValueNodeValueJob::Key() const +{ + return fKey; +} + + +status_t +WriteValueNodeValueJob::Do() +{ + ValueNodeContainer* container = fValueNode->Container(); + if (container == NULL) + return B_BAD_VALUE; + + ValueWriter writer(fArchitecture, fDebuggerInterface, + fCpuState, -1); + + BVariant value; + fNewValue->ToVariant(value); + + status_t error = writer.WriteValue(fValueNode->Location(), value); + if (error != B_OK) + return error; + + AutoLocker containerLocker(container); + fValueNode->SetLocationAndValue(fValueNode->Location(), fNewValue, B_OK); + + return B_OK; +} diff --git a/src/apps/debugger/user_interface/UserInterface.h b/src/apps/debugger/user_interface/UserInterface.h index 65caaa7ffb..b87fedf44f 100644 --- a/src/apps/debugger/user_interface/UserInterface.h +++ b/src/apps/debugger/user_interface/UserInterface.h @@ -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 USER_INTERFACE_H @@ -30,9 +30,9 @@ class Thread; class TypeComponentPath; class UserBreakpoint; class UserInterfaceListener; +class Value; class ValueNode; class ValueNodeContainer; -class Variable; class Watchpoint; @@ -101,6 +101,8 @@ public: virtual void ValueNodeValueRequested(CpuState* cpuState, ValueNodeContainer* container, ValueNode* valueNode) = 0; + virtual void ValueNodeWriteRequested(ValueNode* node, + CpuState* state, Value* newValue) = 0; virtual void ThreadActionRequested(thread_id threadID, uint32 action, target_addr_t address = 0) = 0;