More UI support for watchpointgs.

- BreakpointTableModel now encapsulates both breakpoints and watchpoints.
- Extended BreakpointView and TeamWindow to handle enable/disable/removing
  watchpoints as well.
This commit is contained in:
Rene Gollent
2012-11-07 14:52:00 +01:00
parent c1e45a1e82
commit 12c53499e7
11 changed files with 304 additions and 27 deletions
+1
View File
@@ -29,6 +29,7 @@ enum {
MSG_IMAGE_FILE_CHANGED = 'ifch', MSG_IMAGE_FILE_CHANGED = 'ifch',
MSG_FUNCTION_SOURCE_CODE_CHANGED = 'fnsc', MSG_FUNCTION_SOURCE_CODE_CHANGED = 'fnsc',
MSG_USER_BREAKPOINT_CHANGED = 'ubrc', MSG_USER_BREAKPOINT_CHANGED = 'ubrc',
MSG_WATCHPOINT_CHANGED = 'wapc',
MSG_DEBUGGER_EVENT = 'dbge', MSG_DEBUGGER_EVENT = 'dbge',
MSG_LOAD_SETTINGS = 'ldst', MSG_LOAD_SETTINGS = 'ldst',
+12 -2
View File
@@ -74,6 +74,12 @@ WatchpointManager::InstallWatchpoint(Watchpoint* watchpoint,
watchpoint->SetInstalled(false); watchpoint->SetInstalled(false);
} }
if (error == B_OK) {
if (fTeam->WatchpointAtAddress(watchpoint->Address()) == NULL)
fTeam->AddWatchpoint(watchpoint);
fTeam->NotifyWatchpointChanged(watchpoint);
}
return error; return error;
} }
@@ -84,12 +90,16 @@ WatchpointManager::UninstallWatchpoint(Watchpoint* watchpoint)
AutoLocker<BLocker> installLocker(fLock); AutoLocker<BLocker> installLocker(fLock);
AutoLocker<Team> teamLocker(fTeam); AutoLocker<Team> teamLocker(fTeam);
fTeam->RemoveWatchpoint(watchpoint);
if (!watchpoint->IsInstalled()) if (!watchpoint->IsInstalled())
return; return;
status_t error = fDebuggerInterface->UninstallWatchpoint( status_t error = fDebuggerInterface->UninstallWatchpoint(
watchpoint->Address()); watchpoint->Address());
if (error == B_OK) if (error == B_OK) {
watchpoint->SetInstalled(false); watchpoint->SetInstalled(false);
} fTeam->NotifyWatchpointChanged(watchpoint);
}
}
+3
View File
@@ -92,6 +92,9 @@ Team::~Team()
for (int32 i = 0; Breakpoint* breakpoint = fBreakpoints.ItemAt(i); i++) for (int32 i = 0; Breakpoint* breakpoint = fBreakpoints.ItemAt(i); i++)
breakpoint->ReleaseReference(); breakpoint->ReleaseReference();
for (int32 i = 0; Watchpoint* watchpoint = fWatchpoints.ItemAt(i); i++)
watchpoint->ReleaseReference();
while (Image* image = fImages.RemoveHead()) while (Image* image = fImages.RemoveHead())
image->ReleaseReference(); image->ReleaseReference();
+2 -1
View File
@@ -145,6 +145,8 @@ public:
TargetAddressRange range, TargetAddressRange range,
BObjectList<Watchpoint>& watchpoints) BObjectList<Watchpoint>& watchpoints)
const; const;
const WatchpointList& Watchpoints() const
{ return fWatchpoints; }
status_t GetStatementAtAddress(target_addr_t address, status_t GetStatementAtAddress(target_addr_t address,
FunctionInstance*& _function, FunctionInstance*& _function,
@@ -187,7 +189,6 @@ private:
typedef BObjectList<Breakpoint> BreakpointList; typedef BObjectList<Breakpoint> BreakpointList;
typedef DoublyLinkedList<Listener> ListenerList; typedef DoublyLinkedList<Listener> ListenerList;
typedef BObjectList<Watchpoint> WatchpointList;
private: private:
void _NotifyThreadAdded(Thread* thread); void _NotifyThreadAdded(Thread* thread);
+4
View File
@@ -6,6 +6,7 @@
#define WATCHPOINT_H #define WATCHPOINT_H
#include <ObjectList.h>
#include <Referenceable.h> #include <Referenceable.h>
#include "types/Types.h" #include "types/Types.h"
@@ -49,4 +50,7 @@ private:
}; };
typedef BObjectList<Watchpoint> WatchpointList;
#endif // WATCHPOINT_H #endif // WATCHPOINT_H
@@ -18,9 +18,10 @@
#include "GuiSettingsUtils.h" #include "GuiSettingsUtils.h"
#include "LocatableFile.h" #include "LocatableFile.h"
#include "table/TableColumns.h" #include "table/TableColumns.h"
#include "TargetAddressTableColumn.h"
#include "Team.h" #include "Team.h"
#include "UserBreakpoint.h" #include "UserBreakpoint.h"
#include "TargetAddressTableColumn.h" #include "Watchpoint.h"
// #pragma mark - BreakpointsTableModel // #pragma mark - BreakpointsTableModel
@@ -32,16 +33,18 @@ public:
: :
fTeam(team) fTeam(team)
{ {
Update(NULL); UpdateBreakpoint(NULL);
UpdateWatchpoint(NULL);
} }
~BreakpointsTableModel() ~BreakpointsTableModel()
{ {
fTeam = NULL; fTeam = NULL;
Update(NULL); UpdateBreakpoint(NULL);
UpdateWatchpoint(NULL);
} }
bool Update(UserBreakpoint* changedBreakpoint) bool UpdateBreakpoint(UserBreakpoint* changedBreakpoint)
{ {
if (fTeam == NULL) { if (fTeam == NULL) {
for (int32 i = 0; for (int32 i = 0;
@@ -93,6 +96,59 @@ public:
return true; return true;
} }
bool UpdateWatchpoint(Watchpoint* changedWatchpoint)
{
if (fTeam == NULL) {
for (int32 i = 0;
Watchpoint* watchpoint = fWatchpoints.ItemAt(i);
i++) {
watchpoint->ReleaseReference();
}
fWatchpoints.MakeEmpty();
return true;
}
AutoLocker<Team> locker(fTeam);
int32 breakpointCount = fBreakpoints.CountItems();
int32 index = 0;
int32 teamIndex = 0;
Watchpoint* newWatchpoint = fTeam->WatchpointAt(teamIndex);
// remove no longer existing breakpoints
while (Watchpoint* oldWatchpoint = fWatchpoints.ItemAt(index)) {
if (oldWatchpoint == newWatchpoint) {
if (oldWatchpoint == changedWatchpoint)
NotifyRowsChanged(index + breakpointCount, 1);
index++;
teamIndex++;
newWatchpoint = fTeam->WatchpointAt(teamIndex);
} else {
// TODO: Not particularly efficient!
fWatchpoints.RemoveItemAt(index);
oldWatchpoint->ReleaseReference();
NotifyRowsRemoved(index + breakpointCount, 1);
}
}
// add new breakpoints
int32 countBefore = fWatchpoints.CountItems();
while (newWatchpoint != NULL) {
if (!fWatchpoints.AddItem(newWatchpoint))
return false;
newWatchpoint->AcquireReference();
teamIndex++;
newWatchpoint = fTeam->WatchpointAt(teamIndex);
}
int32 count = fWatchpoints.CountItems();
if (count > countBefore)
NotifyRowsAdded(countBefore + breakpointCount, count - countBefore);
return true;
}
virtual int32 CountColumns() const virtual int32 CountColumns() const
{ {
return 5; return 5;
@@ -100,10 +156,33 @@ public:
virtual int32 CountRows() const virtual int32 CountRows() const
{ {
return fBreakpoints.CountItems(); return fBreakpoints.CountItems() + fWatchpoints.CountItems();
} }
virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, BVariant& value) virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, BVariant& value)
{
int32 breakpointCount = fBreakpoints.CountItems();
if (rowIndex < breakpointCount)
return _GetBreakpointValueAt(rowIndex, columnIndex, value);
return _GetWatchpointValueAt(rowIndex - breakpointCount, columnIndex,
value);
}
UserBreakpoint* BreakpointAt(int32 index) const
{
return fBreakpoints.ItemAt(index);
}
Watchpoint* WatchpointAt(int32 index) const
{
return fWatchpoints.ItemAt(index - fBreakpoints.CountItems());
}
private:
bool _GetBreakpointValueAt(int32 rowIndex, int32 columnIndex,
BVariant &value)
{ {
UserBreakpoint* breakpoint = fBreakpoints.ItemAt(rowIndex); UserBreakpoint* breakpoint = fBreakpoints.ItemAt(rowIndex);
if (breakpoint == NULL) if (breakpoint == NULL)
@@ -145,14 +224,36 @@ public:
} }
} }
UserBreakpoint* BreakpointAt(int32 index) const bool _GetWatchpointValueAt(int32 rowIndex, int32 columnIndex,
BVariant& value)
{ {
return fBreakpoints.ItemAt(index); Watchpoint* watchpoint = fWatchpoints.ItemAt(rowIndex);
if (watchpoint == NULL)
return false;
switch (columnIndex) {
case 0:
value.SetTo((int32)watchpoint->IsEnabled());
return true;
case 1:
value.SetTo("Watchpoint");
return true;
case 2:
return false;
case 3:
return false;
case 4:
value.SetTo(watchpoint->Address());
return true;
default:
return false;
}
} }
private: private:
Team* fTeam; Team* fTeam;
BObjectList<UserBreakpoint> fBreakpoints; BObjectList<UserBreakpoint> fBreakpoints;
BObjectList<Watchpoint> fWatchpoints;
}; };
@@ -202,7 +303,8 @@ BreakpointListView::UnsetListener()
void void
BreakpointListView::SetBreakpoint(UserBreakpoint* breakpoint) BreakpointListView::SetBreakpoint(UserBreakpoint* breakpoint,
Watchpoint* watchpoint)
{ {
if (breakpoint == fBreakpoint) if (breakpoint == fBreakpoint)
return; return;
@@ -232,7 +334,14 @@ BreakpointListView::SetBreakpoint(UserBreakpoint* breakpoint)
void void
BreakpointListView::UserBreakpointChanged(UserBreakpoint* breakpoint) BreakpointListView::UserBreakpointChanged(UserBreakpoint* breakpoint)
{ {
fBreakpointsTableModel->Update(breakpoint); fBreakpointsTableModel->UpdateBreakpoint(breakpoint);
}
void
BreakpointListView::WatchpointChanged(Watchpoint* watchpoint)
{
fBreakpointsTableModel->UpdateWatchpoint(watchpoint);
} }
@@ -271,8 +380,13 @@ BreakpointListView::TableSelectionChanged(Table* table)
TableSelectionModel* selectionModel = table->SelectionModel(); TableSelectionModel* selectionModel = table->SelectionModel();
UserBreakpoint* breakpoint = fBreakpointsTableModel->BreakpointAt( UserBreakpoint* breakpoint = fBreakpointsTableModel->BreakpointAt(
selectionModel->RowAt(0)); selectionModel->RowAt(0));
if (breakpoint != NULL)
fListener->BreakpointSelectionChanged(breakpoint); fListener->BreakpointSelectionChanged(breakpoint);
else {
Watchpoint* watchpoint = fBreakpointsTableModel->WatchpointAt(
selectionModel->RowAt(0));
fListener->WatchpointSelectionChanged(watchpoint);
}
} }
@@ -13,6 +13,7 @@
class Team; class Team;
class UserBreakpoint; class UserBreakpoint;
class Watchpoint;
class BreakpointListView : public BGroupView, private TableListener { class BreakpointListView : public BGroupView, private TableListener {
@@ -29,9 +30,13 @@ public:
void UnsetListener(); void UnsetListener();
void SetBreakpoint(UserBreakpoint* breakpoint); void SetBreakpoint(UserBreakpoint* breakpoint,
Watchpoint* watchpoint);
void UserBreakpointChanged( void UserBreakpointChanged(
UserBreakpoint* breakpoint); UserBreakpoint* breakpoint);
void WatchpointChanged(
Watchpoint* breakpoint);
void LoadSettings(const BMessage& settings); void LoadSettings(const BMessage& settings);
status_t SaveSettings(BMessage& settings); status_t SaveSettings(BMessage& settings);
@@ -48,6 +53,7 @@ private:
private: private:
Team* fTeam; Team* fTeam;
UserBreakpoint* fBreakpoint; UserBreakpoint* fBreakpoint;
Watchpoint* fWatchpoint;
Table* fBreakpointsTable; Table* fBreakpointsTable;
BreakpointsTableModel* fBreakpointsTableModel; BreakpointsTableModel* fBreakpointsTableModel;
Listener* fListener; Listener* fListener;
@@ -60,6 +66,9 @@ public:
virtual void BreakpointSelectionChanged( virtual void BreakpointSelectionChanged(
UserBreakpoint* breakpoint) = 0; UserBreakpoint* breakpoint) = 0;
virtual void WatchpointSelectionChanged(
Watchpoint* watchpoint) = 0;
}; };
@@ -68,20 +68,26 @@ BreakpointsView::UnsetListener()
void void
BreakpointsView::SetBreakpoint(UserBreakpoint* breakpoint) BreakpointsView::SetBreakpoint(UserBreakpoint* breakpoint, Watchpoint* watchpoint)
{ {
if (breakpoint == fBreakpoint) if (breakpoint == fBreakpoint && watchpoint == fWatchpoint)
return; return;
if (fWatchpoint != NULL)
fWatchpoint->ReleaseReference();
if (fBreakpoint != NULL) if (fBreakpoint != NULL)
fBreakpoint->ReleaseReference(); fBreakpoint->ReleaseReference();
fWatchpoint = watchpoint;
fBreakpoint = breakpoint; fBreakpoint = breakpoint;
if (fBreakpoint != NULL) if (fBreakpoint != NULL)
fBreakpoint->AcquireReference(); fBreakpoint->AcquireReference();
else if (fWatchpoint != NULL)
fWatchpoint->AcquireReference();
fListView->SetBreakpoint(breakpoint); fListView->SetBreakpoint(breakpoint, watchpoint);
_UpdateButtons(); _UpdateButtons();
} }
@@ -96,21 +102,49 @@ BreakpointsView::UserBreakpointChanged(UserBreakpoint* breakpoint)
} }
void
BreakpointsView::WatchpointChanged(Watchpoint* watchpoint)
{
fListView->WatchpointChanged(watchpoint);
_UpdateButtons();
}
void void
BreakpointsView::MessageReceived(BMessage* message) BreakpointsView::MessageReceived(BMessage* message)
{ {
switch (message->what) { switch (message->what) {
case MSG_ENABLE_BREAKPOINT: case MSG_ENABLE_BREAKPOINT:
if (fListener != NULL && fBreakpoint != NULL) if (fListener != NULL) {
fListener->SetBreakpointEnabledRequested(fBreakpoint, true); if (fBreakpoint != NULL) {
fListener->SetBreakpointEnabledRequested(fBreakpoint,
true);
} else if (fWatchpoint != NULL) {
fListener->SetWatchpointEnabledRequested(fWatchpoint,
true);
}
}
break; break;
case MSG_DISABLE_BREAKPOINT: case MSG_DISABLE_BREAKPOINT:
if (fListener != NULL && fBreakpoint != NULL) if (fListener != NULL) {
fListener->SetBreakpointEnabledRequested(fBreakpoint, false); if (fBreakpoint != NULL) {
fListener->SetBreakpointEnabledRequested(fBreakpoint,
false);
} else if (fWatchpoint != NULL) {
fListener->SetWatchpointEnabledRequested(fWatchpoint,
false);
}
}
break; break;
case MSG_CLEAR_BREAKPOINT: case MSG_CLEAR_BREAKPOINT:
if (fListener != NULL && fBreakpoint != NULL) if (fListener != NULL) {
fListener->ClearBreakpointRequested(fBreakpoint); if (fBreakpoint != NULL) {
fListener->ClearBreakpointRequested(fBreakpoint);
} else if (fWatchpoint != NULL) {
fListener->ClearWatchpointRequested(fWatchpoint);
}
}
break; break;
default: default:
BGroupView::MessageReceived(message); BGroupView::MessageReceived(message);
@@ -159,6 +193,14 @@ BreakpointsView::BreakpointSelectionChanged(UserBreakpoint* breakpoint)
} }
void
BreakpointsView::WatchpointSelectionChanged(Watchpoint* watchpoint)
{
if (fListener != NULL)
fListener->WatchpointSelectionChanged(watchpoint);
}
void void
BreakpointsView::_Init() BreakpointsView::_Init()
{ {
@@ -182,8 +224,19 @@ BreakpointsView::_UpdateButtons()
{ {
AutoLocker<Team> teamLocker(fTeam); AutoLocker<Team> teamLocker(fTeam);
bool enabled = false;
bool valid = false;
if (fBreakpoint != NULL && fBreakpoint->IsValid()) { if (fBreakpoint != NULL && fBreakpoint->IsValid()) {
if (fBreakpoint->IsEnabled()) { valid = true;
enabled = fBreakpoint->IsEnabled();
} else if (fWatchpoint != NULL) {
valid = true;
enabled = fWatchpoint->IsEnabled();
}
if (valid) {
if (enabled) {
fToggleBreakpointButton->SetLabel("Disable"); fToggleBreakpointButton->SetLabel("Disable");
fToggleBreakpointButton->SetMessage( fToggleBreakpointButton->SetMessage(
new BMessage(MSG_DISABLE_BREAKPOINT)); new BMessage(MSG_DISABLE_BREAKPOINT));
@@ -28,9 +28,13 @@ public:
void UnsetListener(); void UnsetListener();
void SetBreakpoint(UserBreakpoint* breakpoint); void SetBreakpoint(UserBreakpoint* breakpoint,
Watchpoint* watchpoint);
void UserBreakpointChanged( void UserBreakpointChanged(
UserBreakpoint* breakpoint); UserBreakpoint* breakpoint);
void WatchpointChanged(
Watchpoint* watchpoint);
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual void AttachedToWindow(); virtual void AttachedToWindow();
@@ -42,6 +46,8 @@ private:
// BreakpointListView::Listener // BreakpointListView::Listener
virtual void BreakpointSelectionChanged( virtual void BreakpointSelectionChanged(
UserBreakpoint* breakpoint); UserBreakpoint* breakpoint);
virtual void WatchpointSelectionChanged(
Watchpoint* watchpoint);
void _Init(); void _Init();
@@ -50,6 +56,7 @@ private:
private: private:
Team* fTeam; Team* fTeam;
UserBreakpoint* fBreakpoint; UserBreakpoint* fBreakpoint;
Watchpoint* fWatchpoint;
BreakpointListView* fListView; BreakpointListView* fListView;
BButton* fToggleBreakpointButton; BButton* fToggleBreakpointButton;
BButton* fRemoveBreakpointButton; BButton* fRemoveBreakpointButton;
@@ -57,6 +64,7 @@ private:
}; };
class BreakpointsView::Listener { class BreakpointsView::Listener {
public: public:
virtual ~Listener(); virtual ~Listener();
@@ -68,6 +76,14 @@ public:
bool enabled) = 0; bool enabled) = 0;
virtual void ClearBreakpointRequested( virtual void ClearBreakpointRequested(
UserBreakpoint* breakpoint) = 0; UserBreakpoint* breakpoint) = 0;
virtual void WatchpointSelectionChanged(
Watchpoint* Watchpoint) = 0;
virtual void SetWatchpointEnabledRequested(
Watchpoint* breakpoint,
bool enabled) = 0;
virtual void ClearWatchpointRequested(
Watchpoint* watchpoint) = 0;
}; };
@@ -356,6 +356,18 @@ TeamWindow::MessageReceived(BMessage* message)
break; break;
} }
case MSG_WATCHPOINT_CHANGED:
{
Watchpoint* watchpoint;
if (message->FindPointer("watchpoint", (void**)&watchpoint) != B_OK)
break;
BReference<Watchpoint> watchpointReference(watchpoint, true);
_HandleWatchpointChanged(watchpoint);
break;
}
case MSG_FUNCTION_SOURCE_CODE_CHANGED: case MSG_FUNCTION_SOURCE_CODE_CHANGED:
{ {
_HandleSourceCodeChanged(); _HandleSourceCodeChanged();
@@ -584,6 +596,28 @@ TeamWindow::ClearBreakpointRequested(target_addr_t address)
} }
void
TeamWindow::WatchpointSelectionChanged(Watchpoint* watchpoint)
{
fBreakpointsView->SetBreakpoint(NULL, watchpoint);
}
void
TeamWindow::SetWatchpointEnabledRequested(Watchpoint* watchpoint,
bool enabled)
{
fListener->SetWatchpointEnabledRequested(watchpoint, enabled);
}
void
TeamWindow::ClearWatchpointRequested(Watchpoint* watchpoint)
{
fListener->ClearWatchpointRequested(watchpoint);
}
void void
TeamWindow::ValueNodeValueRequested(CpuState* cpuState, TeamWindow::ValueNodeValueRequested(CpuState* cpuState,
ValueNodeContainer* container, ValueNode* valueNode) ValueNodeContainer* container, ValueNode* valueNode)
@@ -640,6 +674,18 @@ TeamWindow::UserBreakpointChanged(const Team::UserBreakpointEvent& event)
} }
void
TeamWindow::WatchpointChanged(const Team::WatchpointEvent& event)
{
BMessage message(MSG_WATCHPOINT_CHANGED);
BReference<Watchpoint> watchpointReference(event.GetWatchpoint());
if (message.AddPointer("watchpoint", event.GetWatchpoint()) == B_OK
&& PostMessage(&message) == B_OK) {
watchpointReference.Detach();
}
}
void void
TeamWindow::FunctionSourceCodeChanged(Function* function) TeamWindow::FunctionSourceCodeChanged(Function* function)
{ {
@@ -923,7 +969,7 @@ TeamWindow::_SetActiveBreakpoint(UserBreakpoint* breakpoint)
_ScrollToActiveFunction(); _ScrollToActiveFunction();
} }
fBreakpointsView->SetBreakpoint(fActiveBreakpoint); fBreakpointsView->SetBreakpoint(fActiveBreakpoint, NULL);
} }
@@ -1266,6 +1312,13 @@ TeamWindow::_HandleUserBreakpointChanged(UserBreakpoint* breakpoint)
} }
void
TeamWindow::_HandleWatchpointChanged(Watchpoint* watchpoint)
{
fBreakpointsView->WatchpointChanged(watchpoint);
}
void void
TeamWindow::_HandleResolveMissingSourceFile(entry_ref& locatedPath) TeamWindow::_HandleResolveMissingSourceFile(entry_ref& locatedPath)
{ {
@@ -95,6 +95,15 @@ private:
virtual void ClearBreakpointRequested( virtual void ClearBreakpointRequested(
UserBreakpoint* breakpoint); UserBreakpoint* breakpoint);
virtual void WatchpointSelectionChanged(
Watchpoint* Watchpoint);
virtual void SetWatchpointEnabledRequested(
Watchpoint* breakpoint,
bool enabled);
virtual void ClearWatchpointRequested(
Watchpoint* watchpoint);
// SourceView::Listener // SourceView::Listener
virtual void SetBreakpointRequested(target_addr_t address, virtual void SetBreakpointRequested(target_addr_t address,
bool enabled); bool enabled);
@@ -116,6 +125,8 @@ private:
const Team::ImageEvent& event); const Team::ImageEvent& event);
virtual void UserBreakpointChanged( virtual void UserBreakpointChanged(
const Team::UserBreakpointEvent& event); const Team::UserBreakpointEvent& event);
virtual void WatchpointChanged(
const Team::WatchpointEvent& event);
// Function::Listener // Function::Listener
virtual void FunctionSourceCodeChanged(Function* function); virtual void FunctionSourceCodeChanged(Function* function);
@@ -142,6 +153,8 @@ private:
void _HandleSourceCodeChanged(); void _HandleSourceCodeChanged();
void _HandleUserBreakpointChanged( void _HandleUserBreakpointChanged(
UserBreakpoint* breakpoint); UserBreakpoint* breakpoint);
void _HandleWatchpointChanged(
Watchpoint* watchpoint);
void _HandleResolveMissingSourceFile(entry_ref& void _HandleResolveMissingSourceFile(entry_ref&
locatedPath); locatedPath);