* Move expression evaluation to the inspector window.

* Actually start rendering the memory data. Still has some drawing glitches
  when scrolling though, will look into those tomorrow. Also doesn't yet
  highlight the location which the target address actually points to within
  the block.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42167 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rene Gollent
2011-06-14 02:28:55 +00:00
parent eff23a8157
commit 348e6deb98
9 changed files with 195 additions and 102 deletions
+2 -43
View File
@@ -14,7 +14,6 @@
#include <Message.h> #include <Message.h>
#include <ExpressionParser.h>
#include <AutoLocker.h> #include <AutoLocker.h>
#include "debug_utils.h" #include "debug_utils.h"
@@ -468,12 +467,8 @@ TeamDebugger::MessageReceived(BMessage* message)
break; break;
} }
const char* addressExpression;
target_addr_t address; target_addr_t address;
if (message->FindString("addressExpression", if (message->FindUInt64("address",
&addressExpression) == B_OK) {
_HandleInspectAddress(addressExpression, listener);
} else if (message->FindUInt64("address",
&address) == B_OK) { &address) == B_OK) {
_HandleInspectAddress(address, listener); _HandleInspectAddress(address, listener);
} }
@@ -695,17 +690,6 @@ 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 void
TeamDebugger::InspectRequested(target_addr_t address, TeamDebugger::InspectRequested(target_addr_t address,
TeamMemoryBlock::Listener *listener) TeamMemoryBlock::Listener *listener)
@@ -1300,37 +1284,12 @@ 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 void
TeamDebugger::_HandleInspectAddress(target_addr_t address, TeamDebugger::_HandleInspectAddress(target_addr_t address,
TeamMemoryBlock::Listener* listener) TeamMemoryBlock::Listener* listener)
{ {
TRACE_CONTROL("TeamDebugger::_HandleInspectAddress(" B_PRIx64 ", %p)\n", TRACE_CONTROL("TeamDebugger::_HandleInspectAddress(" B_PRIx64 ", %p)\n",
addressExpression, listener); address, listener);
TeamMemoryBlock* memoryBlock = fMemoryBlockManager TeamMemoryBlock* memoryBlock = fMemoryBlockManager
->GetMemoryBlock(address); ->GetMemoryBlock(address);
-5
View File
@@ -68,8 +68,6 @@ private:
UserBreakpoint* breakpoint); UserBreakpoint* breakpoint);
virtual void InspectRequested(target_addr_t address, virtual void InspectRequested(target_addr_t address,
TeamMemoryBlock::Listener* listener); TeamMemoryBlock::Listener* listener);
virtual void InspectRequested(const char* addressExpression,
TeamMemoryBlock::Listener* listener);
virtual bool UserInterfaceQuitRequested(); virtual bool UserInterfaceQuitRequested();
// JobListener // JobListener
@@ -126,9 +124,6 @@ private:
void _HandleInspectAddress( void _HandleInspectAddress(
target_addr_t address, target_addr_t address,
TeamMemoryBlock::Listener* listener); TeamMemoryBlock::Listener* listener);
void _HandleInspectAddress(
const char* addressExpression,
TeamMemoryBlock::Listener* listener);
ThreadHandler* _GetThreadHandler(thread_id threadID); ThreadHandler* _GetThreadHandler(thread_id threadID);
@@ -77,6 +77,14 @@ TeamMemoryBlock::Invalidate()
} }
bool
TeamMemoryBlock::Contains(target_addr_t address) const
{
return fValid && address >= fBaseAddress
&& address < (fBaseAddress + sizeof(fData));
}
void void
TeamMemoryBlock::SetWritable(bool writable) TeamMemoryBlock::SetWritable(bool writable)
{ {
@@ -39,6 +39,7 @@ public:
target_addr_t BaseAddress() const { return fBaseAddress; }; target_addr_t BaseAddress() const { return fBaseAddress; };
uint8* Data() { return fData; }; uint8* Data() { return fData; };
size_t Size() const { return sizeof(fData); }; size_t Size() const { return sizeof(fData); };
bool Contains(target_addr_t address) const;
bool IsWritable() const { return fWritable; } bool IsWritable() const { return fWritable; }
void SetWritable(bool writable); void SetWritable(bool writable);
@@ -86,9 +86,6 @@ public:
virtual void InspectRequested( virtual void InspectRequested(
target_addr_t address, target_addr_t address,
TeamMemoryBlock::Listener* listener) = 0; TeamMemoryBlock::Listener* listener) = 0;
virtual void InspectRequested(
const char* addressExpression,
TeamMemoryBlock::Listener* listener) = 0;
virtual bool UserInterfaceQuitRequested() = 0; virtual bool UserInterfaceQuitRequested() = 0;
}; };
@@ -5,13 +5,16 @@
#include "InspectorWindow.h" #include "InspectorWindow.h"
#include <stdio.h>
#include <Alert.h>
#include <Application.h> #include <Application.h>
#include <Button.h> #include <Button.h>
#include <LayoutBuilder.h> #include <LayoutBuilder.h>
#include <ScrollView.h> #include <ScrollView.h>
#include <TextControl.h> #include <TextControl.h>
#include <stdio.h> #include <ExpressionParser.h>
#include "MemoryView.h" #include "MemoryView.h"
#include "MessageCodes.h" #include "MessageCodes.h"
@@ -20,9 +23,11 @@
InspectorWindow::InspectorWindow(UserInterfaceListener* listener) InspectorWindow::InspectorWindow(UserInterfaceListener* listener)
: :
BWindow(BRect(100, 100, 500, 250), "Inspector", B_DOCUMENT_WINDOW, BWindow(BRect(100, 100, 500, 250), "Inspector", B_TITLED_WINDOW,
B_ASYNCHRONOUS_CONTROLS), B_ASYNCHRONOUS_CONTROLS),
fListener(listener) fListener(listener),
fMemoryView(NULL),
fCurrentBlock(NULL)
{ {
} }
@@ -51,13 +56,18 @@ InspectorWindow::Create(UserInterfaceListener* listener)
void void
InspectorWindow::_Init() InspectorWindow::_Init()
{ {
BScrollView* scrollView;
BLayoutBuilder::Group<>(this, B_VERTICAL) BLayoutBuilder::Group<>(this, B_VERTICAL)
.Add(fAddressInput = new BTextControl("addrInput", .Add(fAddressInput = new BTextControl("addrInput",
"Target Address:", "", "Target Address:", "",
new BMessage(MSG_INSPECT_ADDRESS))) new BMessage(MSG_INSPECT_ADDRESS)))
.Add(fMemoryView = new MemoryView(NULL, NULL)) .Add(scrollView = new BScrollView("memory scroll",
NULL, 0, false, true), 3.0f)
.End(); .End();
scrollView->SetTarget(fMemoryView = MemoryView::Create());
fAddressInput->SetTarget(this); fAddressInput->SetTarget(this);
} }
@@ -69,8 +79,43 @@ InspectorWindow::MessageReceived(BMessage* msg)
switch (msg->what) { switch (msg->what) {
case MSG_INSPECT_ADDRESS: case MSG_INSPECT_ADDRESS:
{ {
ExpressionParser parser;
parser.SetSupportHexInput(true);
target_addr_t address = 0;
const char* addressExpression = fAddressInput->Text(); const char* addressExpression = fAddressInput->Text();
fListener->InspectRequested(addressExpression, this); BString errorMessage;
try {
address = parser.EvaluateToInt64(addressExpression);
} catch(ParseException parseError) {
errorMessage.SetToFormat("Failed to parse address: %s",
parseError.message.String());
} catch(...) {
errorMessage.SetToFormat(
"Unknown error while parsing address");
}
if (errorMessage.Length() > 0) {
BAlert* alert = new(std::nothrow) BAlert("Inspect Address",
errorMessage.String(), "Close");
if (alert != NULL)
alert->Go();
} else {
if (fCurrentBlock != NULL
&& !fCurrentBlock->Contains(address)) {
fCurrentBlock->ReleaseReference();
fCurrentBlock = NULL;
}
if (fCurrentBlock == NULL)
fListener->InspectRequested(address, this);
else
fMemoryView->SetTargetAddress(fCurrentBlock, address);
fCurrentAddress = address;
BString computedAddress;
computedAddress.SetToFormat("0x%" B_PRIx64, address);
fAddressInput->SetText(computedAddress.String());
}
break; break;
} }
} }
@@ -88,5 +133,7 @@ InspectorWindow::QuitRequested()
void void
InspectorWindow::MemoryBlockRetrieved(TeamMemoryBlock* block) InspectorWindow::MemoryBlockRetrieved(TeamMemoryBlock* block)
{ {
// TODO: implement fCurrentBlock = block;
fMemoryView->SetTargetAddress(block, fCurrentAddress);
} }
@@ -40,6 +40,8 @@ private:
UserInterfaceListener* fListener; UserInterfaceListener* fListener;
BTextControl* fAddressInput; BTextControl* fAddressInput;
MemoryView* fMemoryView; MemoryView* fMemoryView;
TeamMemoryBlock* fCurrentBlock;
target_addr_t fCurrentAddress;
}; };
#endif // INSPECTOR_WINDOW_H #endif // INSPECTOR_WINDOW_H
@@ -6,26 +6,40 @@
#include "MemoryView.h" #include "MemoryView.h"
#include <stdio.h>
MemoryView::MemoryView(Team* team, Listener* listener) #include <Messenger.h>
#include <ScrollView.h>
#include <String.h>
#include "TeamMemoryBlock.h"
enum {
MSG_TARGET_ADDRESS_CHANGED = 'mtac'
};
MemoryView::MemoryView()
: :
BView("memoryView", B_WILL_DRAW | B_SUBPIXEL_PRECISE), BView("memoryView", B_WILL_DRAW | B_FRAME_EVENTS | B_SUBPIXEL_PRECISE),
fTeam(team), fTargetBlock(NULL),
fListener(listener) fTargetAddress(0)
{ {
} }
MemoryView::~MemoryView() MemoryView::~MemoryView()
{ {
UnsetListener(); if (fTargetBlock != NULL)
fTargetBlock->ReleaseReference();
} }
/*static */ MemoryView* /*static */ MemoryView*
MemoryView::Create(Team* team, Listener* listener) MemoryView::Create()
{ {
MemoryView* self = new MemoryView(team, listener); MemoryView* self = new MemoryView();
try { try {
self->_Init(); self->_Init();
@@ -39,24 +53,15 @@ MemoryView::Create(Team* team, Listener* listener)
void void
MemoryView::UnsetListener() MemoryView::SetTargetAddress(TeamMemoryBlock* block, target_addr_t address)
{
fListener = NULL;
}
void
MemoryView::SetTargetAddress(target_addr_t address)
{ {
fTargetAddress = address; fTargetAddress = address;
Invalidate(); if (fTargetBlock != NULL)
} fTargetBlock->ReleaseReference();
fTargetBlock = block;
void fTargetBlock->AcquireReference();
MemoryView::TargetAddressChanged(target_addr_t address) BMessenger(this).SendMessage(MSG_TARGET_ADDRESS_CHANGED);
{
SetTargetAddress(address);
} }
@@ -64,6 +69,21 @@ void
MemoryView::TargetedByScrollView(BScrollView* scrollView) MemoryView::TargetedByScrollView(BScrollView* scrollView)
{ {
BView::TargetedByScrollView(scrollView); BView::TargetedByScrollView(scrollView);
scrollView->ScrollBar(B_VERTICAL)->SetRange(0.0, 0.0);
}
void
MemoryView::AttachedToWindow()
{
BView::AttachedToWindow();
SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR));
SetFont(be_fixed_font);
fCharWidth = be_fixed_font->StringWidth("a");
font_height fontHeight;
be_fixed_font->GetHeight(&fontHeight);
fLineHeight = fontHeight.ascent + fontHeight.descent
+ fontHeight.leading;
} }
@@ -71,6 +91,48 @@ void
MemoryView::Draw(BRect rect) MemoryView::Draw(BRect rect)
{ {
BView::Draw(rect); BView::Draw(rect);
StrokeLine(BPoint(9 * fCharWidth, rect.top),
BPoint(9 * fCharWidth, rect.bottom));
if (fTargetBlock == NULL)
return;
int32 startLine = (int32)rect.top / fLineHeight;
int32 bytesPerLine = fNybblesPerLine / 2;
int32 startByte = bytesPerLine * startLine;
target_addr_t currentAddress = fTargetBlock->BaseAddress() + startByte;
target_addr_t maxAddress = fTargetBlock->BaseAddress()
+ fTargetBlock->Size();
BPoint drawPoint(1.0, rect.top);
BString tempData;
int32 currentBytesPerLine = bytesPerLine;
for (int32 i = startLine; drawPoint.y < rect.bottom
&& currentAddress < maxAddress; i++, drawPoint.y += fLineHeight) {
drawPoint.x = 1.0;
tempData.SetToFormat("%" B_PRIx32 " ",
currentAddress);
DrawString(tempData.String(), drawPoint);
drawPoint.x += fCharWidth * 10;
if (currentAddress + bytesPerLine > maxAddress)
currentBytesPerLine = maxAddress - currentAddress;
for (int32 j = 0; j < currentBytesPerLine; j += 2) {
tempData.SetToFormat("%04" B_PRIx16 " ",
*((uint16*)&fTargetBlock->Data()[i * bytesPerLine + j]));
DrawString(tempData.String(), drawPoint);
drawPoint.x += fCharWidth * 5;
}
currentAddress += bytesPerLine;
}
}
void
MemoryView::FrameResized(float width, float height)
{
BView::FrameResized(width, height);
_RecalcScrollBars();
Invalidate();
} }
@@ -78,12 +140,21 @@ void
MemoryView::MessageReceived(BMessage* message) MemoryView::MessageReceived(BMessage* message)
{ {
switch(message->what) { switch(message->what) {
case MSG_TARGET_ADDRESS_CHANGED:
{
_RecalcScrollBars();
Invalidate();
break;
}
default: default:
{
BView::MessageReceived(message); BView::MessageReceived(message);
break; break;
}
} }
} }
void void
MemoryView::_Init() MemoryView::_Init()
{ {
@@ -91,6 +162,25 @@ MemoryView::_Init()
} }
MemoryView::Listener::~Listener() void
MemoryView::_RecalcScrollBars()
{ {
float max = 0.0;
BScrollBar *scrollBar = ScrollBar(B_VERTICAL);
if (fTargetBlock != NULL) {
BRect bounds = Bounds();
fNybblesPerLine = bounds.Width() / fCharWidth;
// we allocate 8 characters for the starting address of the current
// line plus some spacing to separate that from the data
fNybblesPerLine -= 10;
// also allocate a space between each 16-bit grouping
fNybblesPerLine -= (fNybblesPerLine / 4);
fNybblesPerLine &= ~3;
int32 lineCount = ceil(2 * fTargetBlock->Size() / fNybblesPerLine);
float totalHeight = lineCount * fLineHeight;
max = totalHeight - bounds.Height();
scrollBar->SetProportion(bounds.Height() / totalHeight);
scrollBar->SetSteps(fLineHeight, bounds.Height());
}
scrollBar->SetRange(0.0, max);
} }
@@ -9,49 +9,43 @@
#include <View.h> #include <View.h>
#include "Team.h" #include "Types.h"
class TeamMemoryBlock;
class MemoryView : public BView { class MemoryView : public BView {
public: public:
class Listener; MemoryView();
public:
MemoryView(
Team* team, Listener* listener);
virtual ~MemoryView(); virtual ~MemoryView();
static MemoryView* Create(Team* team, Listener* listener); static MemoryView* Create();
// throws // throws
void UnsetListener(); void SetTargetAddress(TeamMemoryBlock* block,
target_addr_t address);
void SetTargetAddress(target_addr_t address);
void TargetAddressChanged(target_addr_t address); void TargetAddressChanged(target_addr_t address);
virtual void TargetedByScrollView(BScrollView* scrollView); virtual void TargetedByScrollView(BScrollView* scrollView);
virtual void AttachedToWindow();
virtual void Draw(BRect rect); virtual void Draw(BRect rect);
virtual void FrameResized(float width, float height);
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
private: private:
void _Init(); void _Init();
void _RecalcScrollBars();
private: private:
Team* fTeam; TeamMemoryBlock* fTargetBlock;
target_addr_t fTargetAddress; target_addr_t fTargetAddress;
Listener* fListener; float fCharWidth;
float fLineHeight;
int32 fNybblesPerLine;
}; };
class MemoryView::Listener {
public:
virtual ~Listener();
virtual void SetTargetAddressRequested(
target_addr_t address) = 0;
};
#endif // MEMORY_VIEW_H #endif // MEMORY_VIEW_H