* Moved TargetAddressTableColumn into own source file in gui/util.

* Fixed misspelled MSG_*_BREAKPONT constants.
* model/Team: Added separate event class UserBreakpointEvent for user
  breakpoints.
* SourceView::MarkerManager: Invalidate the markers when new source code is
  set.
* Added breakpoints view.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33578 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-10-14 05:03:00 +00:00
parent 5f73bbcdce
commit 0fc8a75c02
18 changed files with 980 additions and 98 deletions
+10 -10
View File
@@ -104,13 +104,8 @@ BreakpointManager::InstallUserBreakpoint(UserBreakpoint* userBreakpoint,
userBreakpoint->SetEnabled(enabled);
// notify user breakpoint listeners
if (error == B_OK) {
for (int32 i = 0;
UserBreakpointInstance* instance = userBreakpoint->InstanceAt(i);
i++) {
fTeam->NotifyUserBreakpointChanged(instance->GetBreakpoint());
}
}
if (error == B_OK)
fTeam->NotifyUserBreakpointChanged(userBreakpoint);
teamLocker.Unlock();
@@ -138,6 +133,8 @@ BreakpointManager::InstallUserBreakpoint(UserBreakpoint* userBreakpoint,
userBreakpoint->SetValid(true);
userBreakpoint->AcquireReference();
fTeam->AddUserBreakpoint(userBreakpoint);
fTeam->NotifyUserBreakpointChanged(userBreakpoint);
// notify again -- the breakpoint hadn't been added before
teamLocker.Unlock();
}
} else {
@@ -164,12 +161,15 @@ BreakpointManager::InstallUserBreakpoint(UserBreakpoint* userBreakpoint,
_UpdateBreakpointInstallation(breakpoint);
teamLocker.Lock();
fTeam->NotifyUserBreakpointChanged(breakpoint);
if (breakpoint->IsUnused())
fTeam->RemoveBreakpoint(breakpoint);
teamLocker.Unlock();
}
teamLocker.Lock();
fTeam->NotifyUserBreakpointChanged(userBreakpoint);
teamLocker.Unlock();
}
}
@@ -211,13 +211,13 @@ BreakpointManager::UninstallUserBreakpoint(UserBreakpoint* userBreakpoint)
instance->SetBreakpoint(NULL);
breakpoint->RemoveUserBreakpoint(instance);
fTeam->NotifyUserBreakpointChanged(breakpoint);
if (breakpoint->IsUnused())
fTeam->RemoveBreakpoint(breakpoint);
}
}
fTeam->NotifyUserBreakpointChanged(userBreakpoint);
teamLocker.Unlock();
installLocker.Unlock();
+6
View File
@@ -14,6 +14,7 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) elf ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) files ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) gui model ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) gui team_window ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) gui util ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) ids ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) model ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) settings ] ;
@@ -98,6 +99,8 @@ Application Debugger :
VariablesViewStateHistory.cpp
# gui/team_window
BreakpointListView.cpp
BreakpointsView.cpp
ImageFunctionsView.cpp
ImageListView.cpp
RegistersView.cpp
@@ -107,6 +110,9 @@ Application Debugger :
ThreadListView.cpp
VariablesView.cpp
# gui/util
TargetAddressTableColumn.cpp
# ids
FunctionID.cpp
LocalVariableID.cpp
+4 -2
View File
@@ -12,8 +12,10 @@ enum {
MSG_THREAD_STEP_OVER = 'stov',
MSG_THREAD_STEP_INTO = 'stin',
MSG_THREAD_STEP_OUT = 'stou',
MSG_SET_BREAKPONT = 'sbrk',
MSG_CLEAR_BREAKPONT = 'cbrk',
MSG_SET_BREAKPOINT = 'sbrk',
MSG_CLEAR_BREAKPOINT = 'cbrk',
MSG_ENABLE_BREAKPOINT = 'ebrk',
MSG_DISABLE_BREAKPOINT = 'dbrk',
MSG_THREAD_STATE_CHANGED = 'tsch',
MSG_THREAD_CPU_STATE_CHANGED = 'tcsc',
+65 -13
View File
@@ -408,21 +408,34 @@ TeamDebugger::MessageReceived(BMessage* message)
break;
}
case MSG_SET_BREAKPONT:
case MSG_CLEAR_BREAKPONT:
case MSG_SET_BREAKPOINT:
case MSG_CLEAR_BREAKPOINT:
{
uint64 address;
if (message->FindUInt64("address", &address) != B_OK)
UserBreakpoint* breakpoint = NULL;
Reference<UserBreakpoint> breakpointReference;
uint64 address = 0;
if (message->FindPointer("breakpoint", (void**)&breakpoint) == B_OK)
breakpointReference.SetTo(breakpoint, true);
else if (message->FindUInt64("address", &address) != B_OK)
break;
if (message->what == MSG_SET_BREAKPONT) {
if (message->what == MSG_SET_BREAKPOINT) {
bool enabled;
if (message->FindBool("enabled", &enabled) != B_OK)
enabled = true;
_HandleSetUserBreakpoint(address, enabled);
} else
_HandleClearUserBreakpoint(address);
if (breakpoint != NULL)
_HandleSetUserBreakpoint(breakpoint, enabled);
else
_HandleSetUserBreakpoint(address, enabled);
} else {
if (breakpoint != NULL)
_HandleClearUserBreakpoint(breakpoint);
else
_HandleClearUserBreakpoint(address);
}
break;
}
@@ -587,22 +600,48 @@ TeamDebugger::ThreadActionRequested(thread_id threadID,
void
TeamDebugger::SetBreakpointRequested(target_addr_t address, bool enabled)
{
BMessage message(MSG_SET_BREAKPONT);
BMessage message(MSG_SET_BREAKPOINT);
message.AddUInt64("address", (uint64)address);
message.AddBool("enabled", enabled);
PostMessage(&message);
}
void
TeamDebugger::SetBreakpointEnabledRequested(UserBreakpoint* breakpoint,
bool enabled)
{
BMessage message(MSG_SET_BREAKPOINT);
Reference<UserBreakpoint> breakpointReference(breakpoint);
if (message.AddPointer("breakpoint", breakpoint) == B_OK
&& message.AddBool("enabled", enabled) == B_OK
&& PostMessage(&message) == B_OK) {
breakpointReference.Detach();
}
}
void
TeamDebugger::ClearBreakpointRequested(target_addr_t address)
{
BMessage message(MSG_CLEAR_BREAKPONT);
BMessage message(MSG_CLEAR_BREAKPOINT);
message.AddUInt64("address", (uint64)address);
PostMessage(&message);
}
void
TeamDebugger::ClearBreakpointRequested(UserBreakpoint* breakpoint)
{
BMessage message(MSG_CLEAR_BREAKPOINT);
Reference<UserBreakpoint> breakpointReference(breakpoint);
if (message.AddPointer("breakpoint", breakpoint) == B_OK
&& PostMessage(&message) == B_OK) {
breakpointReference.Detach();
}
}
bool
TeamDebugger::TeamWindowQuitRequested()
{
@@ -720,7 +759,6 @@ TeamDebugger::_DebugEventListener()
break;
// TODO: Error handling!
if (event->Team() != fTeamID) {
TRACE_EVENTS("TeamDebugger for team %ld: received event from team "
"%ld!\n", fTeamID, event->Team());
@@ -1101,7 +1139,14 @@ TeamDebugger::_HandleSetUserBreakpoint(target_addr_t address, bool enabled)
locker.Unlock();
status_t error = fBreakpointManager->InstallUserBreakpoint(userBreakpoint,
_HandleSetUserBreakpoint(userBreakpoint, enabled);
}
void
TeamDebugger::_HandleSetUserBreakpoint(UserBreakpoint* breakpoint, bool enabled)
{
status_t error = fBreakpointManager->InstallUserBreakpoint(breakpoint,
enabled);
if (error != B_OK) {
_NotifyUser("Install Breakpoint", "Failed to install breakpoint: %s",
@@ -1126,7 +1171,14 @@ TeamDebugger::_HandleClearUserBreakpoint(target_addr_t address)
locker.Unlock();
fBreakpointManager->UninstallUserBreakpoint(userBreakpoint);
_HandleClearUserBreakpoint(userBreakpoint);
}
void
TeamDebugger::_HandleClearUserBreakpoint(UserBreakpoint* breakpoint)
{
fBreakpointManager->UninstallUserBreakpoint(breakpoint);
}
+9
View File
@@ -53,7 +53,12 @@ private:
uint32 action);
virtual void SetBreakpointRequested(target_addr_t address,
bool enabled);
virtual void SetBreakpointEnabledRequested(
UserBreakpoint* breakpoint,
bool enabled);
virtual void ClearBreakpointRequested(target_addr_t address);
virtual void ClearBreakpointRequested(
UserBreakpoint* breakpoint);
virtual bool TeamWindowQuitRequested();
// JobListener
@@ -96,8 +101,12 @@ private:
void _HandleSetUserBreakpoint(target_addr_t address,
bool enabled);
void _HandleSetUserBreakpoint(
UserBreakpoint* breakpoint, bool enabled);
void _HandleClearUserBreakpoint(
target_addr_t address);
void _HandleClearUserBreakpoint(
UserBreakpoint* breakpoint);
ThreadHandler* _GetThreadHandler(thread_id threadID);
@@ -0,0 +1,282 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "BreakpointListView.h"
#include <stdio.h>
#include <new>
#include <AutoLocker.h>
#include <ObjectList.h>
#include "FunctionID.h"
#include "LocatableFile.h"
#include "table/TableColumns.h"
#include "Team.h"
#include "UserBreakpoint.h"
#include "TargetAddressTableColumn.h"
// #pragma mark - BreakpointsTableModel
class BreakpointListView::BreakpointsTableModel : public TableModel {
public:
BreakpointsTableModel(Team* team)
:
fTeam(team)
{
Update(NULL);
}
~BreakpointsTableModel()
{
fTeam = NULL;
Update(NULL);
}
bool Update(UserBreakpoint* changedBreakpoint)
{
if (fTeam == NULL) {
for (int32 i = 0;
UserBreakpoint* breakpoint = fBreakpoints.ItemAt(i);
i++) {
breakpoint->RemoveReference();
}
fBreakpoints.MakeEmpty();
return true;
}
AutoLocker<Team> locker(fTeam);
UserBreakpointList::ConstIterator it
= fTeam->UserBreakpoints().GetIterator();
UserBreakpoint* newBreakpoint = it.Next();
int32 index = 0;
// remove no longer existing breakpoints
while (UserBreakpoint* oldBreakpoint = fBreakpoints.ItemAt(index)) {
if (oldBreakpoint == newBreakpoint) {
if (oldBreakpoint == changedBreakpoint)
NotifyRowsChanged(index, 1);
index++;
newBreakpoint = it.Next();
} else {
// TODO: Not particularly efficient!
fBreakpoints.RemoveItemAt(index);
oldBreakpoint->RemoveReference();
NotifyRowsRemoved(index, 1);
}
}
// add new breakpoints
int32 countBefore = fBreakpoints.CountItems();
while (newBreakpoint != NULL) {
if (!fBreakpoints.AddItem(newBreakpoint))
return false;
newBreakpoint->AddReference();
newBreakpoint = it.Next();
}
int32 count = fBreakpoints.CountItems();
if (count > countBefore)
NotifyRowsAdded(countBefore, count - countBefore);
return true;
}
virtual int32 CountColumns() const
{
return 5;
}
virtual int32 CountRows() const
{
return fBreakpoints.CountItems();
}
virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, BVariant& value)
{
UserBreakpoint* breakpoint = fBreakpoints.ItemAt(rowIndex);
if (breakpoint == NULL)
return false;
const UserBreakpointLocation& location = breakpoint->Location();
switch (columnIndex) {
case 0:
value.SetTo((int32)breakpoint->IsEnabled());
return true;
case 1:
value.SetTo(location.GetFunctionID()->FunctionName(),
B_VARIANT_DONT_COPY_DATA);
return true;
case 2:
if (LocatableFile* sourceFile = location.SourceFile()) {
value.SetTo(sourceFile->Name(), B_VARIANT_DONT_COPY_DATA);
return true;
}
return false;
case 3:
if (location.SourceFile() != NULL) {
value.SetTo(location.GetSourceLocation().Line() + 1);
return true;
}
return false;
case 4:
if (location.SourceFile() == NULL) {
AutoLocker<Team> teamLocker(fTeam);
if (UserBreakpointInstance* instance
= breakpoint->InstanceAt(0)) {
value.SetTo(instance->Address());
return true;
}
}
return false;
default:
return false;
}
}
UserBreakpoint* BreakpointAt(int32 index) const
{
return fBreakpoints.ItemAt(index);
}
private:
Team* fTeam;
BObjectList<UserBreakpoint> fBreakpoints;
};
// #pragma mark - BreakpointListView
BreakpointListView::BreakpointListView(Team* team, Listener* listener)
:
BGroupView(B_VERTICAL),
fTeam(team),
fBreakpoint(NULL),
fBreakpointsTable(NULL),
fBreakpointsTableModel(NULL),
fListener(listener)
{
}
BreakpointListView::~BreakpointListView()
{
fBreakpointsTable->SetTableModel(NULL);
delete fBreakpointsTableModel;
}
/*static*/ BreakpointListView*
BreakpointListView::Create(Team* team, Listener* listener)
{
BreakpointListView* self = new BreakpointListView(team, listener);
try {
self->_Init();
} catch (...) {
delete self;
throw;
}
return self;
}
void
BreakpointListView::UnsetListener()
{
fListener = NULL;
}
void
BreakpointListView::SetBreakpoint(UserBreakpoint* breakpoint)
{
if (breakpoint == fBreakpoint)
return;
if (fBreakpoint != NULL)
fBreakpoint->ReleaseReference();
fBreakpoint = breakpoint;
if (fBreakpoint != NULL) {
fBreakpoint->AcquireReference();
for (int32 i = 0;
UserBreakpoint* other = fBreakpointsTableModel->BreakpointAt(i);
i++) {
if (fBreakpoint == other) {
fBreakpointsTable->SelectRow(i, false);
return;
}
}
}
fBreakpointsTable->DeselectAllRows();
}
void
BreakpointListView::UserBreakpointChanged(UserBreakpoint* breakpoint)
{
fBreakpointsTableModel->Update(breakpoint);
}
void
BreakpointListView::TableSelectionChanged(Table* table)
{
if (fListener == NULL)
return;
TableSelectionModel* selectionModel = table->SelectionModel();
UserBreakpoint* breakpoint = fBreakpointsTableModel->BreakpointAt(
selectionModel->RowAt(0));
fListener->BreakpointSelectionChanged(breakpoint);
}
void
BreakpointListView::_Init()
{
fBreakpointsTable = new Table("breakpoints list", 0, B_FANCY_BORDER);
AddChild(fBreakpointsTable->ToView());
// columns
fBreakpointsTable->AddColumn(new BoolStringTableColumn(0, "State", 70, 20,
1000, "Enabled", "Disabled"));
fBreakpointsTable->AddColumn(new StringTableColumn(1, "Function", 250, 40,
1000, B_TRUNCATE_END, B_ALIGN_LEFT));
fBreakpointsTable->AddColumn(new StringTableColumn(2, "File", 250, 40,
1000, B_TRUNCATE_END, B_ALIGN_LEFT));
fBreakpointsTable->AddColumn(new Int32TableColumn(3, "Line", 60, 20,
1000, B_TRUNCATE_END, B_ALIGN_RIGHT));
fBreakpointsTable->AddColumn(new TargetAddressTableColumn(4, "Address", 100,
20, 1000, B_TRUNCATE_END, B_ALIGN_RIGHT));
fBreakpointsTable->SetSelectionMode(B_SINGLE_SELECTION_LIST);
fBreakpointsTable->AddTableListener(this);
fBreakpointsTableModel = new BreakpointsTableModel(fTeam);
fBreakpointsTable->SetTableModel(fBreakpointsTableModel);
}
// #pragma mark - Listener
BreakpointListView::Listener::~Listener()
{
}
@@ -0,0 +1,63 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef BREAKPOINT_LIST_VIEW_H
#define BREAKPOINT_LIST_VIEW_H
#include <GroupView.h>
#include "table/Table.h"
class Team;
class UserBreakpoint;
class BreakpointListView : public BGroupView, private TableListener {
public:
class Listener;
public:
BreakpointListView(Team* team,
Listener* listener);
~BreakpointListView();
static BreakpointListView* Create(Team* team, Listener* listener);
// throws
void UnsetListener();
void SetBreakpoint(UserBreakpoint* breakpoint);
void UserBreakpointChanged(
UserBreakpoint* breakpoint);
private:
class BreakpointsTableModel;
private:
// TableListener
virtual void TableSelectionChanged(Table* table);
void _Init();
private:
Team* fTeam;
UserBreakpoint* fBreakpoint;
Table* fBreakpointsTable;
BreakpointsTableModel* fBreakpointsTableModel;
Listener* fListener;
};
class BreakpointListView::Listener {
public:
virtual ~Listener();
virtual void BreakpointSelectionChanged(
UserBreakpoint* breakpoint) = 0;
};
#endif // BREAKPOINT_LIST_VIEW_H
@@ -0,0 +1,186 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "BreakpointsView.h"
#include <new>
#include <Button.h>
#include <LayoutBuilder.h>
#include <AutoLocker.h>
#include <ObjectList.h>
#include "MessageCodes.h"
#include "Team.h"
#include "UserBreakpoint.h"
// #pragma mark - BreakpointsView
BreakpointsView::BreakpointsView(Team* team, Listener* listener)
:
BGroupView(B_HORIZONTAL, 4.0f),
fTeam(team),
fBreakpoint(NULL),
fListView(NULL),
fToggleBreakpointButton(NULL),
fRemoveBreakpointButton(NULL),
fListener(listener)
{
SetName("Breakpoints");
}
BreakpointsView::~BreakpointsView()
{
if (fListView != NULL)
fListView->UnsetListener();
}
/*static*/ BreakpointsView*
BreakpointsView::Create(Team* team, Listener* listener)
{
BreakpointsView* self = new BreakpointsView(team, listener);
try {
self->_Init();
} catch (...) {
delete self;
throw;
}
return self;
}
void
BreakpointsView::UnsetListener()
{
fListener = NULL;
}
void
BreakpointsView::SetBreakpoint(UserBreakpoint* breakpoint)
{
if (breakpoint == fBreakpoint)
return;
if (fBreakpoint != NULL)
fBreakpoint->ReleaseReference();
fBreakpoint = breakpoint;
if (fBreakpoint != NULL)
fBreakpoint->AcquireReference();
fListView->SetBreakpoint(breakpoint);
_UpdateButtons();
}
void
BreakpointsView::UserBreakpointChanged(UserBreakpoint* breakpoint)
{
fListView->UserBreakpointChanged(breakpoint);
_UpdateButtons();
}
void
BreakpointsView::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_ENABLE_BREAKPOINT:
if (fListener != NULL && fBreakpoint != NULL)
fListener->SetBreakpointEnabledRequested(fBreakpoint, true);
break;
case MSG_DISABLE_BREAKPOINT:
if (fListener != NULL && fBreakpoint != NULL)
fListener->SetBreakpointEnabledRequested(fBreakpoint, false);
break;
case MSG_CLEAR_BREAKPOINT:
if (fListener != NULL && fBreakpoint != NULL)
fListener->ClearBreakpointRequested(fBreakpoint);
break;
default:
BGroupView::MessageReceived(message);
break;
}
}
void
BreakpointsView::AttachedToWindow()
{
fToggleBreakpointButton->SetTarget(this);
fRemoveBreakpointButton->SetTarget(this);
}
void
BreakpointsView::BreakpointSelectionChanged(UserBreakpoint* breakpoint)
{
if (fListener != NULL)
fListener->BreakpointSelectionChanged(breakpoint);
}
void
BreakpointsView::_Init()
{
BLayoutBuilder::Group<>(this)
.Add(fListView = BreakpointListView::Create(fTeam, this))
.AddGroup(B_VERTICAL, 4.0f)
.Add(fToggleBreakpointButton = new BButton("Toggle"))
.Add(fRemoveBreakpointButton = new BButton("Remove"))
.AddGlue()
.End();
fToggleBreakpointButton->SetMessage(new BMessage(MSG_ENABLE_BREAKPOINT));
fRemoveBreakpointButton->SetMessage(new BMessage(MSG_CLEAR_BREAKPOINT));
_UpdateButtons();
}
void
BreakpointsView::_UpdateButtons()
{
AutoLocker<Team> teamLocker(fTeam);
if (fBreakpoint != NULL && fBreakpoint->IsValid()) {
if (fBreakpoint->IsEnabled()) {
fToggleBreakpointButton->SetLabel("Disable");
fToggleBreakpointButton->SetMessage(
new BMessage(MSG_DISABLE_BREAKPOINT));
} else {
fToggleBreakpointButton->SetLabel("Enable");
fToggleBreakpointButton->SetMessage(
new BMessage(MSG_ENABLE_BREAKPOINT));
}
fToggleBreakpointButton->SetEnabled(true);
fRemoveBreakpointButton->SetEnabled(true);
} else {
fToggleBreakpointButton->SetLabel("Enable");
fToggleBreakpointButton->SetEnabled(false);
fRemoveBreakpointButton->SetEnabled(false);
}
}
// #pragma mark - Listener
BreakpointsView::Listener::~Listener()
{
}
@@ -0,0 +1,71 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef BREAKPOINTS_VIEW_H
#define BREAKPOINTS_VIEW_H
#include <GroupView.h>
#include "BreakpointListView.h"
class BButton;
class BreakpointsView : public BGroupView,
private BreakpointListView::Listener {
public:
class Listener;
public:
BreakpointsView(Team* team, Listener* listener);
~BreakpointsView();
static BreakpointsView* Create(Team* team, Listener* listener);
// throws
void UnsetListener();
void SetBreakpoint(UserBreakpoint* breakpoint);
void UserBreakpointChanged(
UserBreakpoint* breakpoint);
virtual void MessageReceived(BMessage* message);
virtual void AttachedToWindow();
private:
// BreakpointListView::Listener
virtual void BreakpointSelectionChanged(
UserBreakpoint* breakpoint);
void _Init();
void _UpdateButtons();
private:
Team* fTeam;
UserBreakpoint* fBreakpoint;
BreakpointListView* fListView;
BButton* fToggleBreakpointButton;
BButton* fRemoveBreakpointButton;
Listener* fListener;
};
class BreakpointsView::Listener {
public:
virtual ~Listener();
virtual void BreakpointSelectionChanged(
UserBreakpoint* breakpoint) = 0;
virtual void SetBreakpointEnabledRequested(
UserBreakpoint* breakpoint,
bool enabled) = 0;
virtual void ClearBreakpointRequested(
UserBreakpoint* breakpoint) = 0;
};
#endif // BREAKPOINT_LIST_VIEW_H
@@ -81,7 +81,8 @@ public:
void SetStackTrace(StackTrace* stackTrace);
void SetStackFrame(StackFrame* stackFrame);
void UserBreakpointChanged(target_addr_t address);
void UserBreakpointChanged(
UserBreakpoint* breakpoint);
struct Marker;
struct InstructionPointerMarker;
@@ -145,7 +146,8 @@ public:
void SetStackTrace(StackTrace* stackTrace);
void SetStackFrame(StackFrame* stackFrame);
void UserBreakpointChanged(target_addr_t address);
void UserBreakpointChanged(
UserBreakpoint* breakpoint);
virtual BSize MinSize();
virtual BSize MaxSize();
@@ -236,7 +238,8 @@ public:
FontInfo* fontInfo);
virtual void SetSourceCode(SourceCode* sourceCode);
void UserBreakpointChanged(target_addr_t address);
void UserBreakpointChanged(
UserBreakpoint* breakpoint);
virtual BSize MinSize();
virtual BSize MaxSize();
@@ -530,6 +533,8 @@ void
SourceView::MarkerManager::SetSourceCode(SourceCode* sourceCode)
{
fSourceCode = sourceCode;
_InvalidateIPMarkers();
_InvalidateBreakpointMarkers();
}
@@ -550,7 +555,7 @@ SourceView::MarkerManager::SetStackFrame(StackFrame* stackFrame)
void
SourceView::MarkerManager::UserBreakpointChanged(target_addr_t address)
SourceView::MarkerManager::UserBreakpointChanged(UserBreakpoint* breakpoint)
{
_InvalidateBreakpointMarkers();
}
@@ -827,7 +832,7 @@ SourceView::MarkerView::SetStackFrame(StackFrame* stackFrame)
void
SourceView::MarkerView::UserBreakpointChanged(target_addr_t address)
SourceView::MarkerView::UserBreakpointChanged(UserBreakpoint* breakpoint)
{
Invalidate();
}
@@ -975,7 +980,7 @@ SourceView::TextView::SetSourceCode(SourceCode* sourceCode)
void
SourceView::TextView::UserBreakpointChanged(target_addr_t)
SourceView::TextView::UserBreakpointChanged(UserBreakpoint* breakpoint)
{
Invalidate();
}
@@ -1749,11 +1754,11 @@ SourceView::SetSourceCode(SourceCode* sourceCode)
void
SourceView::UserBreakpointChanged(target_addr_t address)
SourceView::UserBreakpointChanged(UserBreakpoint* breakpoint)
{
fMarkerManager->UserBreakpointChanged(address);
fMarkerView->UserBreakpointChanged(address);
fTextView->UserBreakpointChanged(address);
fMarkerManager->UserBreakpointChanged(breakpoint);
fMarkerView->UserBreakpointChanged(breakpoint);
fTextView->UserBreakpointChanged(breakpoint);
}
@@ -18,6 +18,7 @@ class StackFrame;
class StackTrace;
class Statement;
class Team;
class UserBreakpoint;
class SourceView : public BView {
@@ -37,7 +38,8 @@ public:
void SetStackFrame(StackFrame* stackFrame);
void SetSourceCode(SourceCode* sourceCode);
void UserBreakpointChanged(target_addr_t address);
void UserBreakpointChanged(
UserBreakpoint* breakpoint);
bool ScrollToAddress(target_addr_t address);
bool ScrollToLine(uint32 line);
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License.
*/
#include "StackTraceView.h"
#include <stdio.h>
@@ -14,39 +15,7 @@
#include "FunctionInstance.h"
#include "Image.h"
#include "StackTrace.h"
// #pragma mark - TargetAddressValueColumn
class TargetAddressValueColumn : public StringTableColumn {
public:
TargetAddressValueColumn(int32 modelIndex, const char* title, float width,
float minWidth, float maxWidth, uint32 truncate = B_TRUNCATE_MIDDLE,
alignment align = B_ALIGN_RIGHT)
:
StringTableColumn(modelIndex, title, width, minWidth, maxWidth,
truncate, align)
{
}
protected:
virtual BField* PrepareField(const BVariant& value) const
{
char buffer[64];
snprintf(buffer, sizeof(buffer), "%#llx", value.ToUInt64());
return StringTableColumn::PrepareField(
BVariant(buffer, B_VARIANT_DONT_COPY_DATA));
}
virtual int CompareValues(const BVariant& a, const BVariant& b)
{
uint64 valueA = a.ToUInt64();
uint64 valueB = b.ToUInt64();
return valueA < valueB ? -1 : (valueA == valueB ? 0 : 1);
}
};
#include "TargetAddressTableColumn.h"
// #pragma mark - FramesTableModel
@@ -246,9 +215,9 @@ StackTraceView::_Init()
fFramesTable->SetSortingEnabled(false);
// columns
fFramesTable->AddColumn(new TargetAddressValueColumn(0, "Frame", 80, 40,
fFramesTable->AddColumn(new TargetAddressTableColumn(0, "Frame", 80, 40,
1000, B_TRUNCATE_END, B_ALIGN_RIGHT));
fFramesTable->AddColumn(new TargetAddressValueColumn(1, "IP", 80, 40, 1000,
fFramesTable->AddColumn(new TargetAddressTableColumn(1, "IP", 80, 40, 1000,
B_TRUNCATE_END, B_ALIGN_RIGHT));
fFramesTable->AddColumn(new StringTableColumn(2, "Function", 300, 100, 1000,
B_TRUNCATE_END, B_ALIGN_LEFT));
+127 -17
View File
@@ -54,14 +54,17 @@ TeamWindow::TeamWindow(::Team* team, Listener* listener)
fActiveImage(NULL),
fActiveStackTrace(NULL),
fActiveStackFrame(NULL),
fActiveBreakpoint(NULL),
fActiveFunction(NULL),
fActiveSourceCode(NULL),
fActiveSourceObject(ACTIVE_SOURCE_NONE),
fListener(listener),
fTabView(NULL),
fLocalsTabView(NULL),
fThreadListView(NULL),
fImageListView(NULL),
fImageFunctionsView(NULL),
fBreakpointsView(NULL),
fVariablesView(NULL),
fRegistersView(NULL),
fStackTraceView(NULL),
@@ -95,6 +98,7 @@ TeamWindow::~TeamWindow()
_SetActiveSourceCode(NULL);
_SetActiveFunction(NULL);
_SetActiveBreakpoint(NULL);
_SetActiveStackFrame(NULL);
_SetActiveStackTrace(NULL);
_SetActiveImage(NULL);
@@ -236,11 +240,12 @@ TeamWindow::MessageReceived(BMessage* message)
case MSG_USER_BREAKPOINT_CHANGED:
{
uint64 address;
if (message->FindUInt64("address", &address) != B_OK)
UserBreakpoint* breakpoint;
if (message->FindPointer("breakpoint", (void**)&breakpoint) != B_OK)
break;
Reference<UserBreakpoint> breakpointReference(breakpoint, true);
_HandleUserBreakpointChanged(address);
_HandleUserBreakpointChanged(breakpoint);
break;
}
@@ -288,10 +293,36 @@ TeamWindow::StackFrameSelectionChanged(StackFrame* frame)
void
TeamWindow::FunctionSelectionChanged(FunctionInstance* function)
{
// If the function wasn't already active, it was just selected by the user.
if (function != NULL && function != fActiveFunction)
fActiveSourceObject = ACTIVE_SOURCE_FUNCTION;
_SetActiveFunction(function);
}
void
TeamWindow::BreakpointSelectionChanged(UserBreakpoint* breakpoint)
{
_SetActiveBreakpoint(breakpoint);
}
void
TeamWindow::SetBreakpointEnabledRequested(UserBreakpoint* breakpoint,
bool enabled)
{
fListener->SetBreakpointEnabledRequested(breakpoint, enabled);
}
void
TeamWindow::ClearBreakpointRequested(UserBreakpoint* breakpoint)
{
fListener->ClearBreakpointRequested(breakpoint);
}
void
TeamWindow::SetBreakpointRequested(target_addr_t address, bool enabled)
{
@@ -351,11 +382,14 @@ TeamWindow::ImageDebugInfoChanged(const Team::ImageEvent& event)
void
TeamWindow::UserBreakpointChanged(const Team::BreakpointEvent& event)
TeamWindow::UserBreakpointChanged(const Team::UserBreakpointEvent& event)
{
BMessage message(MSG_USER_BREAKPOINT_CHANGED);
message.AddUInt64("address", event.GetBreakpoint()->Address());
PostMessage(&message);
Reference<UserBreakpoint> breakpointReference(event.GetBreakpoint());
if (message.AddPointer("breakpoint", event.GetBreakpoint()) == B_OK
&& PostMessage(&message) == B_OK) {
breakpointReference.Detach();
}
}
@@ -431,6 +465,14 @@ TeamWindow::_Init()
.Add(fImageListView = ImageListView::Create(fTeam, this))
.Add(fImageFunctionsView = ImageFunctionsView::Create(this));
// add breakpoints tab
BGroupView* breakpointsGroup = new BGroupView(B_HORIZONTAL, 4.0f);
breakpointsGroup->SetName("Breakpoints");
fTabView->AddTab(breakpointsGroup);
BLayoutBuilder::Group<>(breakpointsGroup)
.SetInsets(4.0f, 4.0f, 4.0f, 4.0f)
.Add(fBreakpointsView = BreakpointsView::Create(fTeam, this));
// add local variables tab
BView* tab = fVariablesView = VariablesView::Create(this);
fLocalsTabView->AddTab(tab);
@@ -445,7 +487,7 @@ TeamWindow::_Init()
fStepOutButton->SetMessage(new BMessage(MSG_THREAD_STEP_OUT));
fRunButton->SetTarget(this);
fStepOverButton->SetTarget(this);
fRunButton->SetTarget(this);
fStepIntoButton->SetTarget(this);
fStepOutButton->SetTarget(this);
// add menus and menu items
@@ -579,6 +621,8 @@ TeamWindow::_SetActiveStackFrame(StackFrame* frame)
fActiveStackFrame->AddListener(this);
locker.Unlock();
fActiveSourceObject = ACTIVE_SOURCE_STACK_FRAME;
_SetActiveFunction(fActiveStackFrame->Function());
}
@@ -593,9 +637,50 @@ TeamWindow::_SetActiveStackFrame(StackFrame* frame)
}
void
TeamWindow::_SetActiveBreakpoint(UserBreakpoint* breakpoint)
{
if (breakpoint == fActiveBreakpoint)
return;
if (fActiveBreakpoint != NULL)
fActiveBreakpoint->RemoveReference();
fActiveBreakpoint = breakpoint;
if (fActiveBreakpoint != NULL) {
fActiveBreakpoint->AddReference();
// get the breakpoint's function (more exactly: some function instance)
AutoLocker< ::Team> locker(fTeam);
Function* function = fTeam->FunctionByID(
breakpoint->Location().GetFunctionID());
FunctionInstance* functionInstance = function != NULL
? function->FirstInstance() : NULL;
Reference<FunctionInstance> functionInstanceReference(functionInstance);
locker.Unlock();
fActiveSourceObject = ACTIVE_SOURCE_BREAKPOINT;
_SetActiveFunction(functionInstance);
// scroll to the breakpoint's source code line number (it is not done
// automatically, if the active function remains the same)
_ScrollToActiveFunction();
}
fBreakpointsView->SetBreakpoint(fActiveBreakpoint);
}
void
TeamWindow::_SetActiveFunction(FunctionInstance* functionInstance)
{
// TODO: If a function is selected by other means than via selecting a stack
// frame, we should still select a matching stack frame, if it features the
// same function.
if (functionInstance == fActiveFunction)
return;
@@ -612,9 +697,8 @@ TeamWindow::_SetActiveFunction(FunctionInstance* functionInstance)
fActiveFunction = NULL;
if (functionInstance != NULL) {
if (functionInstance != NULL)
_SetActiveImage(fTeam->ImageByAddress(functionInstance->Address()));
}
fActiveFunction = functionInstance;
@@ -726,12 +810,37 @@ TeamWindow::_UpdateRunButtons()
void
TeamWindow::_ScrollToActiveFunction()
{
// Scroll to the active function, if it doesn't match the stack frame (i.e.
// has been selected manually).
if (fActiveFunction != NULL && fActiveSourceCode != NULL
&& (fActiveStackFrame == NULL
|| fActiveStackFrame->Function() != fActiveFunction)) {
fSourceView->ScrollToAddress(fActiveFunction->Address());
// Scroll to the active function, if it has been selected manually.
if (fActiveFunction == NULL || fActiveSourceCode == NULL)
return;
switch (fActiveSourceObject) {
case ACTIVE_SOURCE_FUNCTION:
fSourceView->ScrollToAddress(fActiveFunction->Address());
break;
case ACTIVE_SOURCE_BREAKPOINT:
{
if (fActiveBreakpoint == NULL)
break;
const UserBreakpointLocation& location
= fActiveBreakpoint->Location();
int32 line = location.GetSourceLocation().Line();
if (location.SourceFile() != NULL && line >= 0
&& fActiveSourceCode->GetSourceFile()
== location.SourceFile()) {
fSourceView->ScrollToLine(line);
} else {
fSourceView->ScrollToAddress(
fActiveFunction->Address()
+ location.RelativeAddress());
}
break;
}
case ACTIVE_SOURCE_NONE:
case ACTIVE_SOURCE_STACK_FRAME:
break;
}
}
@@ -854,9 +963,10 @@ TeamWindow::_HandleSourceCodeChanged()
void
TeamWindow::_HandleUserBreakpointChanged(target_addr_t address)
TeamWindow::_HandleUserBreakpointChanged(UserBreakpoint* breakpoint)
{
fSourceView->UserBreakpointChanged(address);
fSourceView->UserBreakpointChanged(breakpoint);
fBreakpointsView->UserBreakpointChanged(breakpoint);
}
+38 -5
View File
@@ -9,10 +9,11 @@
#include <String.h>
#include <Window.h>
#include "SourceView.h"
#include "BreakpointsView.h"
#include "Function.h"
#include "ImageFunctionsView.h"
#include "ImageListView.h"
#include "SourceView.h"
#include "StackFrame.h"
#include "StackTraceView.h"
#include "Team.h"
@@ -27,13 +28,15 @@ class Image;
class RegistersView;
class SourceCode;
class StackFrame;
class UserBreakpoint;
class VariablesView;
class TeamWindow : public BWindow, ThreadListView::Listener,
ImageListView::Listener, StackTraceView::Listener,
ImageFunctionsView::Listener, SourceView::Listener, VariablesView::Listener,
Team::Listener, Function::Listener, StackFrame::Listener {
ImageFunctionsView::Listener, BreakpointsView::Listener,
SourceView::Listener, VariablesView::Listener, Team::Listener,
Function::Listener, StackFrame::Listener {
public:
class Listener;
@@ -49,6 +52,14 @@ public:
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
private:
enum ActiveSourceObject {
ACTIVE_SOURCE_NONE,
ACTIVE_SOURCE_STACK_FRAME,
ACTIVE_SOURCE_FUNCTION,
ACTIVE_SOURCE_BREAKPOINT
};
private:
// ThreadListView::Listener
virtual void ThreadSelectionChanged(::Thread* thread);
@@ -63,6 +74,15 @@ private:
virtual void FunctionSelectionChanged(
FunctionInstance* function);
// BreakpointsView::Listener
virtual void BreakpointSelectionChanged(
UserBreakpoint* breakpoint);
virtual void SetBreakpointEnabledRequested(
UserBreakpoint* breakpoint,
bool enabled);
virtual void ClearBreakpointRequested(
UserBreakpoint* breakpoint);
// SourceView::Listener
virtual void SetBreakpointRequested(target_addr_t address,
bool enabled);
@@ -83,7 +103,7 @@ private:
virtual void ImageDebugInfoChanged(
const Team::ImageEvent& event);
virtual void UserBreakpointChanged(
const Team::BreakpointEvent& event);
const Team::UserBreakpointEvent& event);
// Function::Listener
virtual void FunctionSourceCodeChanged(Function* function);
@@ -99,6 +119,8 @@ private:
void _SetActiveImage(Image* image);
void _SetActiveStackTrace(StackTrace* stackTrace);
void _SetActiveStackFrame(StackFrame* frame);
void _SetActiveBreakpoint(
UserBreakpoint* breakpoint);
void _SetActiveFunction(FunctionInstance* function);
void _SetActiveSourceCode(SourceCode* sourceCode);
void _UpdateCpuState();
@@ -114,7 +136,7 @@ private:
void _HandleImageDebugInfoChanged(image_id imageID);
void _HandleSourceCodeChanged();
void _HandleUserBreakpointChanged(
target_addr_t address);
UserBreakpoint* breakpoint);
private:
::Team* fTeam;
@@ -122,14 +144,17 @@ private:
Image* fActiveImage;
StackTrace* fActiveStackTrace;
StackFrame* fActiveStackFrame;
UserBreakpoint* fActiveBreakpoint;
FunctionInstance* fActiveFunction;
SourceCode* fActiveSourceCode;
ActiveSourceObject fActiveSourceObject;
Listener* fListener;
BTabView* fTabView;
BTabView* fLocalsTabView;
ThreadListView* fThreadListView;
ImageListView* fImageListView;
ImageFunctionsView* fImageFunctionsView;
BreakpointsView* fBreakpointsView;
VariablesView* fVariablesView;
RegistersView* fRegistersView;
StackTraceView* fStackTraceView;
@@ -155,10 +180,18 @@ public:
// called with team locked
virtual void ThreadActionRequested(thread_id threadID,
uint32 action) = 0;
virtual void SetBreakpointRequested(target_addr_t address,
bool enabled) = 0;
virtual void SetBreakpointEnabledRequested(
UserBreakpoint* breakpoint,
bool enabled) = 0;
virtual void ClearBreakpointRequested(
target_addr_t address) = 0;
virtual void ClearBreakpointRequested(
UserBreakpoint* breakpoint) = 0;
// TODO: Consolidate those!
virtual bool TeamWindowQuitRequested() = 0;
};
@@ -0,0 +1,39 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "TargetAddressTableColumn.h"
#include <stdio.h>
TargetAddressTableColumn::TargetAddressTableColumn(int32 modelIndex,
const char* title, float width, float minWidth, float maxWidth,
uint32 truncate, alignment align)
:
StringTableColumn(modelIndex, title, width, minWidth, maxWidth, truncate,
align)
{
}
BField*
TargetAddressTableColumn::PrepareField(const BVariant& value) const
{
char buffer[64];
snprintf(buffer, sizeof(buffer), "%#llx", value.ToUInt64());
return StringTableColumn::PrepareField(
BVariant(buffer, B_VARIANT_DONT_COPY_DATA));
}
int
TargetAddressTableColumn::CompareValues(const BVariant& a, const BVariant& b)
{
uint64 valueA = a.ToUInt64();
uint64 valueB = b.ToUInt64();
return valueA < valueB ? -1 : (valueA == valueB ? 0 : 1);
}
@@ -0,0 +1,27 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef TARGET_ADDRESS_TABLE_COLUMN_H
#define TARGET_ADDRESS_TABLE_COLUMN_H
#include "table/TableColumns.h"
class TargetAddressTableColumn : public StringTableColumn {
public:
TargetAddressTableColumn(int32 modelIndex,
const char* title, float width,
float minWidth, float maxWidth,
uint32 truncate = B_TRUNCATE_MIDDLE,
alignment align = B_ALIGN_RIGHT);
protected:
virtual BField* PrepareField(const BVariant& value) const;
virtual int CompareValues(const BVariant& a,
const BVariant& b);
};
#endif // TARGET_ADDRESS_TABLE_COLUMN_H
+15 -3
View File
@@ -528,11 +528,11 @@ Team::NotifyImageDebugInfoChanged(Image* image)
void
Team::NotifyUserBreakpointChanged(Breakpoint* breakpoint)
Team::NotifyUserBreakpointChanged(UserBreakpoint* breakpoint)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->UserBreakpointChanged(BreakpointEvent(
listener->UserBreakpointChanged(UserBreakpointEvent(
TEAM_EVENT_USER_BREAKPOINT_CHANGED, this, breakpoint));
}
}
@@ -645,6 +645,18 @@ Team::BreakpointEvent::BreakpointEvent(uint32 type, Team* team,
}
// #pragma mark - UserBreakpointEvent
Team::UserBreakpointEvent::UserBreakpointEvent(uint32 type, Team* team,
UserBreakpoint* breakpoint)
:
Event(type, team),
fBreakpoint(breakpoint)
{
}
// #pragma mark - Listener
@@ -714,6 +726,6 @@ Team::Listener::BreakpointRemoved(const Team::BreakpointEvent& event)
void
Team::Listener::UserBreakpointChanged(const Team::BreakpointEvent& event)
Team::Listener::UserBreakpointChanged(const Team::UserBreakpointEvent& event)
{
}
+16 -2
View File
@@ -48,6 +48,7 @@ class SourceLocation;
class Statement;
class TeamDebugInfo;
class TeamMemory;
class UserBreakpoint;
class Team {
@@ -56,6 +57,7 @@ public:
class ThreadEvent;
class ImageEvent;
class BreakpointEvent;
class UserBreakpointEvent;
class Listener;
public:
@@ -149,7 +151,7 @@ public:
// breakpoint related service methods
void NotifyUserBreakpointChanged(
Breakpoint* breakpoint);
UserBreakpoint* breakpoint);
private:
struct BreakpointByAddressPredicate;
@@ -228,6 +230,18 @@ protected:
};
class Team::UserBreakpointEvent : public Event {
public:
UserBreakpointEvent(uint32 type, Team* team,
UserBreakpoint* breakpoint);
UserBreakpoint* GetBreakpoint() const { return fBreakpoint; }
protected:
UserBreakpoint* fBreakpoint;
};
class Team::Listener : public DoublyLinkedListLinkImpl<Team::Listener> {
public:
virtual ~Listener();
@@ -253,7 +267,7 @@ public:
virtual void BreakpointRemoved(
const Team::BreakpointEvent& event);
virtual void UserBreakpointChanged(
const Team::BreakpointEvent& event);
const Team::UserBreakpointEvent& event);
};