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



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42080 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rene Gollent
2011-06-10 01:58:39 +00:00
parent a99d0dd7b7
commit 3e3ce16f5e
15 changed files with 929 additions and 3 deletions
+107
View File
@@ -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 @@ TeamDebugger::MessageReceived(BMessage* message)
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 @@ TeamDebugger::ClearBreakpointRequested(UserBreakpoint* breakpoint)
}
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 @@ TeamDebugger::_HandleClearUserBreakpoint(UserBreakpoint* breakpoint)
}
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)
{