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