* 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:
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user