From 348e6deb98ae68c9fbe55de2502fa60f1f9e6f4d Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 14 Jun 2011 02:28:55 +0000 Subject: [PATCH] * 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 --- src/apps/debugger/TeamDebugger.cpp | 45 +----- src/apps/debugger/TeamDebugger.h | 5 - src/apps/debugger/model/TeamMemoryBlock.cpp | 8 ++ src/apps/debugger/model/TeamMemoryBlock.h | 1 + .../debugger/user_interface/UserInterface.h | 3 - .../gui/inspector_window/InspectorWindow.cpp | 59 +++++++- .../gui/inspector_window/InspectorWindow.h | 2 + .../gui/inspector_window/MemoryView.cpp | 136 +++++++++++++++--- .../gui/inspector_window/MemoryView.h | 38 +++-- 9 files changed, 195 insertions(+), 102 deletions(-) diff --git a/src/apps/debugger/TeamDebugger.cpp b/src/apps/debugger/TeamDebugger.cpp index c65ce285ab..4d7d149b8b 100644 --- a/src/apps/debugger/TeamDebugger.cpp +++ b/src/apps/debugger/TeamDebugger.cpp @@ -14,7 +14,6 @@ #include -#include #include #include "debug_utils.h" @@ -468,12 +467,8 @@ TeamDebugger::MessageReceived(BMessage* message) break; } - const char* addressExpression; target_addr_t address; - if (message->FindString("addressExpression", - &addressExpression) == B_OK) { - _HandleInspectAddress(addressExpression, listener); - } else if (message->FindUInt64("address", + if (message->FindUInt64("address", &address) == B_OK) { _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 TeamDebugger::InspectRequested(target_addr_t address, 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 TeamDebugger::_HandleInspectAddress(target_addr_t address, TeamMemoryBlock::Listener* listener) { TRACE_CONTROL("TeamDebugger::_HandleInspectAddress(" B_PRIx64 ", %p)\n", - addressExpression, listener); + address, listener); TeamMemoryBlock* memoryBlock = fMemoryBlockManager ->GetMemoryBlock(address); diff --git a/src/apps/debugger/TeamDebugger.h b/src/apps/debugger/TeamDebugger.h index 6b19e06bd9..bd1cf5d267 100644 --- a/src/apps/debugger/TeamDebugger.h +++ b/src/apps/debugger/TeamDebugger.h @@ -68,8 +68,6 @@ private: UserBreakpoint* breakpoint); virtual void InspectRequested(target_addr_t address, TeamMemoryBlock::Listener* listener); - virtual void InspectRequested(const char* addressExpression, - TeamMemoryBlock::Listener* listener); virtual bool UserInterfaceQuitRequested(); // JobListener @@ -126,9 +124,6 @@ private: void _HandleInspectAddress( target_addr_t address, TeamMemoryBlock::Listener* listener); - void _HandleInspectAddress( - const char* addressExpression, - TeamMemoryBlock::Listener* listener); ThreadHandler* _GetThreadHandler(thread_id threadID); diff --git a/src/apps/debugger/model/TeamMemoryBlock.cpp b/src/apps/debugger/model/TeamMemoryBlock.cpp index 64347d55c7..2bae7c303d 100644 --- a/src/apps/debugger/model/TeamMemoryBlock.cpp +++ b/src/apps/debugger/model/TeamMemoryBlock.cpp @@ -77,6 +77,14 @@ TeamMemoryBlock::Invalidate() } +bool +TeamMemoryBlock::Contains(target_addr_t address) const +{ + return fValid && address >= fBaseAddress + && address < (fBaseAddress + sizeof(fData)); +} + + void TeamMemoryBlock::SetWritable(bool writable) { diff --git a/src/apps/debugger/model/TeamMemoryBlock.h b/src/apps/debugger/model/TeamMemoryBlock.h index 893eeb0c05..c02bd67069 100644 --- a/src/apps/debugger/model/TeamMemoryBlock.h +++ b/src/apps/debugger/model/TeamMemoryBlock.h @@ -39,6 +39,7 @@ public: target_addr_t BaseAddress() const { return fBaseAddress; }; uint8* Data() { return fData; }; size_t Size() const { return sizeof(fData); }; + bool Contains(target_addr_t address) const; bool IsWritable() const { return fWritable; } void SetWritable(bool writable); diff --git a/src/apps/debugger/user_interface/UserInterface.h b/src/apps/debugger/user_interface/UserInterface.h index ced05cce32..c5ab2688bf 100644 --- a/src/apps/debugger/user_interface/UserInterface.h +++ b/src/apps/debugger/user_interface/UserInterface.h @@ -86,9 +86,6 @@ public: virtual void InspectRequested( target_addr_t address, TeamMemoryBlock::Listener* listener) = 0; - virtual void InspectRequested( - const char* addressExpression, - TeamMemoryBlock::Listener* listener) = 0; virtual bool UserInterfaceQuitRequested() = 0; }; diff --git a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp index 292777acd3..94158cfee3 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp @@ -5,13 +5,16 @@ #include "InspectorWindow.h" +#include + +#include #include #include #include #include #include -#include +#include #include "MemoryView.h" #include "MessageCodes.h" @@ -20,9 +23,11 @@ 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), - fListener(listener) + fListener(listener), + fMemoryView(NULL), + fCurrentBlock(NULL) { } @@ -51,13 +56,18 @@ InspectorWindow::Create(UserInterfaceListener* listener) void InspectorWindow::_Init() { + BScrollView* scrollView; + BLayoutBuilder::Group<>(this, B_VERTICAL) .Add(fAddressInput = new BTextControl("addrInput", "Target 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(); + scrollView->SetTarget(fMemoryView = MemoryView::Create()); + fAddressInput->SetTarget(this); } @@ -69,8 +79,43 @@ InspectorWindow::MessageReceived(BMessage* msg) switch (msg->what) { case MSG_INSPECT_ADDRESS: { + ExpressionParser parser; + parser.SetSupportHexInput(true); + target_addr_t address = 0; 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; } } @@ -88,5 +133,7 @@ InspectorWindow::QuitRequested() void InspectorWindow::MemoryBlockRetrieved(TeamMemoryBlock* block) { - // TODO: implement + fCurrentBlock = block; + fMemoryView->SetTargetAddress(block, fCurrentAddress); + } diff --git a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h index d4693b8011..867e4f740a 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h +++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h @@ -40,6 +40,8 @@ private: UserInterfaceListener* fListener; BTextControl* fAddressInput; MemoryView* fMemoryView; + TeamMemoryBlock* fCurrentBlock; + target_addr_t fCurrentAddress; }; #endif // INSPECTOR_WINDOW_H diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp index 8733732580..49adf89d24 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp @@ -6,26 +6,40 @@ #include "MemoryView.h" +#include -MemoryView::MemoryView(Team* team, Listener* listener) +#include +#include +#include + +#include "TeamMemoryBlock.h" + + +enum { + MSG_TARGET_ADDRESS_CHANGED = 'mtac' +}; + + +MemoryView::MemoryView() : - BView("memoryView", B_WILL_DRAW | B_SUBPIXEL_PRECISE), - fTeam(team), - fListener(listener) + BView("memoryView", B_WILL_DRAW | B_FRAME_EVENTS | B_SUBPIXEL_PRECISE), + fTargetBlock(NULL), + fTargetAddress(0) { } MemoryView::~MemoryView() { - UnsetListener(); + if (fTargetBlock != NULL) + fTargetBlock->ReleaseReference(); } /*static */ MemoryView* -MemoryView::Create(Team* team, Listener* listener) +MemoryView::Create() { - MemoryView* self = new MemoryView(team, listener); + MemoryView* self = new MemoryView(); try { self->_Init(); @@ -39,24 +53,15 @@ MemoryView::Create(Team* team, Listener* listener) void -MemoryView::UnsetListener() -{ - fListener = NULL; -} - - -void -MemoryView::SetTargetAddress(target_addr_t address) +MemoryView::SetTargetAddress(TeamMemoryBlock* block, target_addr_t address) { fTargetAddress = address; - Invalidate(); -} + if (fTargetBlock != NULL) + fTargetBlock->ReleaseReference(); - -void -MemoryView::TargetAddressChanged(target_addr_t address) -{ - SetTargetAddress(address); + fTargetBlock = block; + fTargetBlock->AcquireReference(); + BMessenger(this).SendMessage(MSG_TARGET_ADDRESS_CHANGED); } @@ -64,6 +69,21 @@ void MemoryView::TargetedByScrollView(BScrollView* 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) { 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) { switch(message->what) { + case MSG_TARGET_ADDRESS_CHANGED: + { + _RecalcScrollBars(); + Invalidate(); + break; + } default: + { BView::MessageReceived(message); break; + } } } + void 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); } diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h index 0fb150dd54..9ae562c923 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h @@ -9,49 +9,43 @@ #include -#include "Team.h" +#include "Types.h" + + +class TeamMemoryBlock; class MemoryView : public BView { public: - class Listener; - -public: - MemoryView( - Team* team, Listener* listener); + MemoryView(); virtual ~MemoryView(); - static MemoryView* Create(Team* team, Listener* listener); + static MemoryView* Create(); // throws - void UnsetListener(); - - void SetTargetAddress(target_addr_t address); + void SetTargetAddress(TeamMemoryBlock* block, + target_addr_t address); void TargetAddressChanged(target_addr_t address); + virtual void TargetedByScrollView(BScrollView* scrollView); + virtual void AttachedToWindow(); virtual void Draw(BRect rect); + virtual void FrameResized(float width, float height); virtual void MessageReceived(BMessage* message); private: void _Init(); + void _RecalcScrollBars(); private: - Team* fTeam; + TeamMemoryBlock* fTargetBlock; 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