Refactoring: Moved TeamDebugModel functionality into Team and got rid of the

former.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31705 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-07-22 19:20:06 +00:00
parent 77777c5389
commit a5e1e7ceba
17 changed files with 398 additions and 573 deletions
+34 -34
View File
@@ -12,14 +12,14 @@
#include <AutoLocker.h>
#include "DebuggerInterface.h"
#include "TeamDebugModel.h"
#include "Team.h"
BreakpointManager::BreakpointManager(TeamDebugModel* debugModel,
BreakpointManager::BreakpointManager(Team* team,
DebuggerInterface* debuggerInterface)
:
fLock("breakpoint manager"),
fDebugModel(debugModel),
fTeam(team),
fDebuggerInterface(debuggerInterface)
{
}
@@ -43,7 +43,7 @@ BreakpointManager::InstallUserBreakpoint(UserBreakpoint* userBreakpoint,
{
printf("BreakpointManager::InstallUserBreakpoint(%p, %d)\n", userBreakpoint, enabled);
AutoLocker<BLocker> installLocker(fLock);
AutoLocker<TeamDebugModel> modelLocker(fDebugModel);
AutoLocker<Team> teamLocker(fTeam);
bool oldEnabled = userBreakpoint->IsEnabled();
if (userBreakpoint->IsValid() && enabled == oldEnabled)
@@ -65,10 +65,10 @@ printf(" -> already has breakpoint\n");
}
target_addr_t address = instance->Address();
Breakpoint* breakpoint = fDebugModel->BreakpointAtAddress(address);
Breakpoint* breakpoint = fTeam->BreakpointAtAddress(address);
if (breakpoint == NULL) {
printf(" -> no breakpoint at that address yet\n");
Image* image = fDebugModel->GetTeam()->ImageByAddress(address);
Image* image = fTeam->ImageByAddress(address);
if (image == NULL) {
printf(" -> no image at that address\n");
error = B_BAD_ADDRESS;
@@ -81,7 +81,7 @@ printf(" -> no image at that address\n");
break;
}
if (!fDebugModel->AddBreakpoint(breakpoint)) {
if (!fTeam->AddBreakpoint(breakpoint)) {
error = B_NO_MEMORY;
break;
}
@@ -102,11 +102,11 @@ printf(" -> adding instance to breakpoint %p\n", breakpoint);
for (int32 i = 0;
UserBreakpointInstance* instance = userBreakpoint->InstanceAt(i);
i++) {
fDebugModel->NotifyUserBreakpointChanged(instance->GetBreakpoint());
fTeam->NotifyUserBreakpointChanged(instance->GetBreakpoint());
}
}
modelLocker.Unlock();
teamLocker.Unlock();
// install/uninstall the breakpoints as needed
printf(" updating breakpoints\n");
@@ -125,18 +125,18 @@ printf(" breakpoint instance %p\n", instance);
printf(" success, marking user breakpoint valid\n");
// everything went fine -- mark the user breakpoint valid
if (!userBreakpoint->IsValid()) {
modelLocker.Lock();
teamLocker.Lock();
userBreakpoint->SetValid(true);
userBreakpoint->AcquireReference();
// TODO: Put the user breakpoint some place?
modelLocker.Unlock();
teamLocker.Unlock();
}
} else {
// something went wrong -- revert the situation
printf(" error, reverting\n");
modelLocker.Lock();
teamLocker.Lock();
userBreakpoint->SetEnabled(oldEnabled);
modelLocker.Unlock();
teamLocker.Unlock();
if (!oldEnabled || !userBreakpoint->IsValid()) {
for (int32 i = 0; UserBreakpointInstance* instance
@@ -153,12 +153,12 @@ printf(" error, reverting\n");
_UpdateBreakpointInstallation(breakpoint);
modelLocker.Lock();
fDebugModel->NotifyUserBreakpointChanged(breakpoint);
teamLocker.Lock();
fTeam->NotifyUserBreakpointChanged(breakpoint);
if (breakpoint->IsUnused())
fDebugModel->RemoveBreakpoint(breakpoint);
modelLocker.Unlock();
fTeam->RemoveBreakpoint(breakpoint);
teamLocker.Unlock();
}
}
}
@@ -173,7 +173,7 @@ void
BreakpointManager::UninstallUserBreakpoint(UserBreakpoint* userBreakpoint)
{
AutoLocker<BLocker> installLocker(fLock);
AutoLocker<TeamDebugModel> modelLocker(fDebugModel);
AutoLocker<Team> teamLocker(fTeam);
if (!userBreakpoint->IsValid())
return;
@@ -181,7 +181,7 @@ BreakpointManager::UninstallUserBreakpoint(UserBreakpoint* userBreakpoint)
userBreakpoint->SetValid(false);
userBreakpoint->SetEnabled(false);
modelLocker.Unlock();
teamLocker.Unlock();
// uninstall the breakpoints as needed
for (int32 i = 0;
@@ -190,7 +190,7 @@ BreakpointManager::UninstallUserBreakpoint(UserBreakpoint* userBreakpoint)
_UpdateBreakpointInstallation(breakpoint);
}
modelLocker.Lock();
teamLocker.Lock();
// detach the breakpoints from the user breakpoint instances
for (int32 i = 0;
@@ -199,14 +199,14 @@ BreakpointManager::UninstallUserBreakpoint(UserBreakpoint* userBreakpoint)
instance->SetBreakpoint(NULL);
breakpoint->RemoveUserBreakpoint(instance);
fDebugModel->NotifyUserBreakpointChanged(breakpoint);
fTeam->NotifyUserBreakpointChanged(breakpoint);
if (breakpoint->IsUnused())
fDebugModel->RemoveBreakpoint(breakpoint);
fTeam->RemoveBreakpoint(breakpoint);
}
}
modelLocker.Unlock();
teamLocker.Unlock();
installLocker.Unlock();
// release the reference from InstallUserBreakpoint()
@@ -219,12 +219,12 @@ BreakpointManager::InstallTemporaryBreakpoint(target_addr_t address,
BreakpointClient* client)
{
AutoLocker<BLocker> installLocker(fLock);
AutoLocker<TeamDebugModel> modelLocker(fDebugModel);
AutoLocker<Team> teamLocker(fTeam);
// create a breakpoint, if it doesn't exist yet
Breakpoint* breakpoint = fDebugModel->BreakpointAtAddress(address);
Breakpoint* breakpoint = fTeam->BreakpointAtAddress(address);
if (breakpoint == NULL) {
Image* image = fDebugModel->GetTeam()->ImageByAddress(address);
Image* image = fTeam->ImageByAddress(address);
if (image == NULL)
return B_BAD_ADDRESS;
@@ -232,7 +232,7 @@ BreakpointManager::InstallTemporaryBreakpoint(target_addr_t address,
if (breakpoint == NULL)
return B_NO_MEMORY;
if (!fDebugModel->AddBreakpoint(breakpoint))
if (!fTeam->AddBreakpoint(breakpoint))
return B_NO_MEMORY;
}
@@ -245,7 +245,7 @@ BreakpointManager::InstallTemporaryBreakpoint(target_addr_t address,
return B_OK;
// install
modelLocker.Unlock();
teamLocker.Unlock();
error = fDebuggerInterface->InstallBreakpoint(address);
if (error == B_OK) {
@@ -253,7 +253,7 @@ BreakpointManager::InstallTemporaryBreakpoint(target_addr_t address,
return B_OK;
}
modelLocker.Lock();
teamLocker.Lock();
breakpoint->RemoveClient(client);
} else
@@ -261,7 +261,7 @@ BreakpointManager::InstallTemporaryBreakpoint(target_addr_t address,
// clean up on error
if (breakpoint->IsUnused())
fDebugModel->RemoveBreakpoint(breakpoint);
fTeam->RemoveBreakpoint(breakpoint);
return error;
}
@@ -272,9 +272,9 @@ BreakpointManager::UninstallTemporaryBreakpoint(target_addr_t address,
BreakpointClient* client)
{
AutoLocker<BLocker> installLocker(fLock);
AutoLocker<TeamDebugModel> modelLocker(fDebugModel);
AutoLocker<Team> teamLocker(fTeam);
Breakpoint* breakpoint = fDebugModel->BreakpointAtAddress(address);
Breakpoint* breakpoint = fTeam->BreakpointAtAddress(address);
if (breakpoint == NULL)
return;
@@ -288,9 +288,9 @@ BreakpointManager::UninstallTemporaryBreakpoint(target_addr_t address,
// if unused remove it
Reference<Breakpoint> breakpointReference(breakpoint);
if (breakpoint->IsUnused())
fDebugModel->RemoveBreakpoint(breakpoint);
fTeam->RemoveBreakpoint(breakpoint);
modelLocker.Unlock();
teamLocker.Unlock();
if (uninstall) {
fDebuggerInterface->UninstallBreakpoint(address);
+3 -3
View File
@@ -11,12 +11,12 @@
class DebuggerInterface;
class TeamDebugModel;
class Team;
class BreakpointManager {
public:
BreakpointManager(TeamDebugModel* debugModel,
BreakpointManager(Team* team,
DebuggerInterface* debuggerInterface);
~BreakpointManager();
@@ -46,7 +46,7 @@ private:
private:
BLocker fLock; // used to synchronize un-/installing
TeamDebugModel* fDebugModel;
Team* fTeam;
DebuggerInterface* fDebuggerInterface;
};
-1
View File
@@ -114,7 +114,6 @@ Application Debugger :
SymbolInfo.cpp
UserBreakpoint.cpp
Team.cpp
TeamDebugModel.cpp
TeamMemory.cpp
Thread.cpp
ThreadInfo.cpp
+4 -6
View File
@@ -25,7 +25,6 @@
#include "StackTrace.h"
#include "Team.h"
#include "TeamDebugInfo.h"
#include "TeamDebugModel.h"
#include "Thread.h"
#include "Type.h"
#include "TypeComponentPath.h"
@@ -443,13 +442,12 @@ GetStackFrameValueJobKey::operator==(const JobKey& other) const
GetStackFrameValueJob::GetStackFrameValueJob(
DebuggerInterface* debuggerInterface, Architecture* architecture,
TeamDebugModel* debugModel, Thread* thread, StackFrame* stackFrame,
Variable* variable, TypeComponentPath* path)
Thread* thread, StackFrame* stackFrame, Variable* variable,
TypeComponentPath* path)
:
fKey(stackFrame, variable, path),
fDebuggerInterface(debuggerInterface),
fArchitecture(architecture),
fDebugModel(debugModel),
fThread(thread),
fStackFrame(stackFrame),
fVariable(variable),
@@ -487,7 +485,7 @@ GetStackFrameValueJob::Do()
// in case of error, set the value to invalid to avoid triggering this job
// again
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker<Team> locker(fThread->GetTeam());
fStackFrame->Values()->SetValue(fVariable->ID(), fPath, BVariant());
return error;
@@ -688,7 +686,7 @@ printf(" -> failed to set typed data: %s\n", strerror(error));
value.SwapEndianess();
// set the value
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker<Team> locker(fThread->GetTeam());
StackFrameValues* values = fStackFrame->Values();
-3
View File
@@ -19,7 +19,6 @@ class Image;
class StackFrame;
class StackFrameValues;
class Team;
class TeamDebugModel;
class Thread;
class TypeComponentPath;
class Variable;
@@ -164,7 +163,6 @@ public:
GetStackFrameValueJob(
DebuggerInterface* debuggerInterface,
Architecture* architecture,
TeamDebugModel* debugModel,
Thread* thread, StackFrame* stackFrame,
Variable* variable,
TypeComponentPath* path);
@@ -183,7 +181,6 @@ private:
GetStackFrameValueJobKey fKey;
DebuggerInterface* fDebuggerInterface;
Architecture* fArchitecture;
TeamDebugModel* fDebugModel;
Thread* fThread;
StackFrame* fStackFrame;
Variable* fVariable;
+14 -25
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License.
*/
#include "TeamDebugger.h"
#include <stdarg.h>
@@ -33,7 +34,6 @@
#include "Statement.h"
#include "SymbolInfo.h"
#include "TeamDebugInfo.h"
#include "TeamDebugModel.h"
#include "Variable.h"
// #pragma mark - ImageHandler
@@ -121,7 +121,6 @@ TeamDebugger::TeamDebugger(Listener* listener)
BLooper("team debugger"),
fListener(listener),
fTeam(NULL),
fDebugModel(NULL),
fTeamID(-1),
fImageHandlers(NULL),
fDebuggerInterface(NULL),
@@ -180,7 +179,6 @@ TeamDebugger::~TeamDebugger()
delete fBreakpointManager;
delete fDebuggerInterface;
delete fWorker;
delete fDebugModel;
delete fTeam;
delete fFileManager;
@@ -234,7 +232,8 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
return error;
// create a team object
fTeam = new(std::nothrow) ::Team(fTeamID, teamDebugInfo);
fTeam = new(std::nothrow) ::Team(fTeamID, fDebuggerInterface,
fDebuggerInterface->GetArchitecture(), teamDebugInfo);
if (fTeam == NULL)
return B_NO_MEMORY;
@@ -269,18 +268,8 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
if (error != B_OK)
return error;
// create the team debug model
fDebugModel = new(std::nothrow) TeamDebugModel(fTeam, fDebuggerInterface,
fDebuggerInterface->GetArchitecture());
if (fDebugModel == NULL)
return B_NO_MEMORY;
error = fDebugModel->Init();
if (error != B_OK)
return error;
// create the breakpoint manager
fBreakpointManager = new(std::nothrow) BreakpointManager(fDebugModel,
fBreakpointManager = new(std::nothrow) BreakpointManager(fTeam,
fDebuggerInterface);
if (fBreakpointManager == NULL)
return B_NO_MEMORY;
@@ -306,8 +295,8 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
if (error != B_OK)
return error;
ThreadHandler* handler = new(std::nothrow) ThreadHandler(
fDebugModel, thread, fWorker, fDebuggerInterface,
ThreadHandler* handler = new(std::nothrow) ThreadHandler(thread,
fWorker, fDebuggerInterface,
fBreakpointManager);
if (handler == NULL)
return B_NO_MEMORY;
@@ -352,7 +341,7 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
// create the team window
try {
fTeamWindow = TeamWindow::Create(fDebugModel, this);
fTeamWindow = TeamWindow::Create(fTeam, this);
} catch (...) {
// TODO: Notify the user!
fprintf(stderr, "Error: Failed to create team window!\n");
@@ -544,8 +533,8 @@ TeamDebugger::StackFrameValueRequested(::Thread* thread, StackFrame* stackFrame,
// schedule the job
if (fWorker->ScheduleJob(
new(std::nothrow) GetStackFrameValueJob(fDebuggerInterface,
fDebuggerInterface->GetArchitecture(), fDebugModel, thread,
stackFrame, variable, path),
fDebuggerInterface->GetArchitecture(), thread, stackFrame,
variable, path),
this) != B_OK) {
// scheduling failed -- set the value to invalid
stackFrame->Values()->SetValue(variable->ID(), path, BVariant());
@@ -818,8 +807,8 @@ TeamDebugger::_HandleThreadCreated(ThreadCreatedEvent* event)
::Thread* thread;
fTeam->AddThread(info, &thread);
ThreadHandler* handler = new(std::nothrow) ThreadHandler(
fDebugModel, thread, fWorker, fDebuggerInterface,
ThreadHandler* handler = new(std::nothrow) ThreadHandler(thread,
fWorker, fDebuggerInterface,
fBreakpointManager);
if (handler != NULL) {
fThreadHandlers.Insert(handler);
@@ -887,7 +876,7 @@ printf("TeamDebugger::_HandleSetUserBreakpoint(%#llx, %d)\n", address, enabled);
// check whether there already is a breakpoint
AutoLocker< ::Team> locker(fTeam);
Breakpoint* breakpoint = fDebugModel->BreakpointAtAddress(address);
Breakpoint* breakpoint = fTeam->BreakpointAtAddress(address);
UserBreakpoint* userBreakpoint = NULL;
if (breakpoint != NULL && breakpoint->FirstUserBreakpoint() != NULL)
userBreakpoint = breakpoint->FirstUserBreakpoint()->GetUserBreakpoint();
@@ -1000,7 +989,7 @@ printf("TeamDebugger::_HandleClearUserBreakpoint(%#llx)\n", address);
AutoLocker< ::Team> locker(fTeam);
Breakpoint* breakpoint = fDebugModel->BreakpointAtAddress(address);
Breakpoint* breakpoint = fTeam->BreakpointAtAddress(address);
if (breakpoint == NULL || breakpoint->FirstUserBreakpoint() == NULL)
return;
UserBreakpoint* userBreakpoint
@@ -1016,7 +1005,7 @@ printf("TeamDebugger::_HandleClearUserBreakpoint(%#llx)\n", address);
ThreadHandler*
TeamDebugger::_GetThreadHandler(thread_id threadID)
{
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
ThreadHandler* handler = fThreadHandlers.Lookup(threadID);
if (handler != NULL)
+1 -2
View File
@@ -5,6 +5,7 @@
#ifndef TEAM_DEBUGGER_H
#define TEAM_DEBUGGER_H
#include <debugger.h>
#include <Looper.h>
@@ -20,7 +21,6 @@
class DebuggerInterface;
class FileManager;
class TeamDebugInfo;
class TeamDebugModel;
class TeamDebugger : public BLooper, private TeamWindow::Listener,
@@ -105,7 +105,6 @@ private:
private:
Listener* fListener;
::Team* fTeam;
TeamDebugModel* fDebugModel;
team_id fTeamID;
ThreadHandlerTable fThreadHandlers;
// protected by the team lock
+10 -11
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License.
*/
#include "ThreadHandler.h"
#include <stdio.h>
@@ -25,7 +26,6 @@
#include "StackTrace.h"
#include "Statement.h"
#include "Team.h"
#include "TeamDebugModel.h"
#include "Worker.h"
@@ -38,11 +38,10 @@ enum {
};
ThreadHandler::ThreadHandler(TeamDebugModel* debugModel, Thread* thread,
Worker* worker, DebuggerInterface* debuggerInterface,
ThreadHandler::ThreadHandler(Thread* thread, Worker* worker,
DebuggerInterface* debuggerInterface,
BreakpointManager* breakpointManager)
:
fDebugModel(debugModel),
fThread(thread),
fWorker(worker),
fDebuggerInterface(debuggerInterface),
@@ -119,8 +118,8 @@ printf("ThreadHandler::HandleBreakpointHit(): ip: %llx\n", instructionPointer);
} else {
// Might be a user breakpoint, but could as well be a temporary
// breakpoint of another thread.
AutoLocker<TeamDebugModel> locker(fDebugModel);
Breakpoint* breakpoint = fDebugModel->BreakpointAtAddress(
AutoLocker<Team> locker(fThread->GetTeam());
Breakpoint* breakpoint = fThread->GetTeam()->BreakpointAtAddress(
cpuState->InstructionPointer());
bool continueThread = false;
if (breakpoint == NULL) {
@@ -187,7 +186,7 @@ ThreadHandler::HandleExceptionOccurred(ExceptionOccurredEvent* event)
void
ThreadHandler::HandleThreadAction(uint32 action)
{
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker<Team> locker(fThread->GetTeam());
if (fThread->State() == THREAD_STATE_UNKNOWN)
return;
@@ -310,7 +309,7 @@ fStepStatement->CoveringAddressRange().End());
void
ThreadHandler::HandleThreadStateChanged()
{
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker<Team> locker(fThread->GetTeam());
// cancel jobs for this thread
fWorker->AbortJob(SimpleJobKey(fThread, JOB_TYPE_GET_CPU_STATE));
@@ -328,7 +327,7 @@ ThreadHandler::HandleThreadStateChanged()
void
ThreadHandler::HandleCpuStateChanged()
{
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker<Team> locker(fThread->GetTeam());
// cancel stack trace job for this thread
fWorker->AbortJob(SimpleJobKey(fThread, JOB_TYPE_GET_STACK_TRACE));
@@ -370,7 +369,7 @@ ThreadHandler::_HandleThreadStopped(CpuState* cpuState)
{
_ClearContinuationState();
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker<Team> locker(fThread->GetTeam());
_SetThreadState(THREAD_STATE_STOPPED, cpuState);
@@ -389,7 +388,7 @@ ThreadHandler::_SetThreadState(uint32 state, CpuState* cpuState)
Statement*
ThreadHandler::_GetStatementAtInstructionPointer(StackFrame* frame)
{
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker<Team> locker(fThread->GetTeam());
FunctionInstance* functionInstance = frame->Function();
if (functionInstance == NULL)
+2 -4
View File
@@ -5,6 +5,7 @@
#ifndef THREAD_HANDLER_H
#define THREAD_HANDLER_H
#include <Referenceable.h>
#include <util/OpenHashTable.h>
@@ -18,7 +19,6 @@ class BreakpointManager;
class DebuggerInterface;
class StackFrame;
class Statement;
class TeamDebugModel;
class Worker;
@@ -26,8 +26,7 @@ class ThreadHandler : public Referenceable,
public HashTableLink<ThreadHandler>, private ImageDebugInfoProvider,
private BreakpointClient {
public:
ThreadHandler(TeamDebugModel* debugModel,
Thread* thread, Worker* worker,
ThreadHandler(Thread* thread, Worker* worker,
DebuggerInterface* debuggerInterface,
BreakpointManager* breakpointManager);
~ThreadHandler();
@@ -90,7 +89,6 @@ private:
bool _HandleSingleStepStep(CpuState* cpuState);
private:
TeamDebugModel* fDebugModel;
Thread* fThread;
Worker* fWorker;
DebuggerInterface* fDebuggerInterface;
@@ -34,7 +34,7 @@
#include "MessageCodes.h"
#include "StackTrace.h"
#include "Statement.h"
#include "TeamDebugModel.h"
#include "Team.h"
static const int32 kLeftTextMargin = 3;
@@ -73,8 +73,7 @@ protected:
class SourceView::MarkerView : public BaseView {
public:
MarkerView(SourceView* sourceView,
TeamDebugModel* debugModel,
MarkerView(SourceView* sourceView, Team* team,
Listener* listener, FontInfo* fontInfo);
~MarkerView();
@@ -129,7 +128,7 @@ public:
const BreakpointMarker* marker);
private:
TeamDebugModel* fDebugModel;
Team* fTeam;
Listener* fListener;
StackTrace* fStackTrace;
StackFrame* fStackFrame;
@@ -477,11 +476,11 @@ SourceView::MarkerView::BreakpointMarker::Draw(MarkerView* view, BRect rect)
// #pragma mark - MarkerView
SourceView::MarkerView::MarkerView(SourceView* sourceView,
TeamDebugModel* debugModel, Listener* listener, FontInfo* fontInfo)
SourceView::MarkerView::MarkerView(SourceView* sourceView, Team* team,
Listener* listener, FontInfo* fontInfo)
:
BaseView("source marker view", sourceView, fontInfo),
fDebugModel(debugModel),
fTeam(team),
fListener(listener),
fStackTrace(NULL),
fStackFrame(NULL),
@@ -610,9 +609,9 @@ SourceView::MarkerView::MouseDown(BPoint where)
if (line < 0)
return;
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker<Team> locker(fTeam);
Statement* statement;
if (fDebugModel->GetTeam()->GetStatementAtSourceLocation(fSourceCode,
if (fTeam->GetStatementAtSourceLocation(fSourceCode,
SourceLocation(line), statement) != B_OK) {
return;
}
@@ -669,14 +668,14 @@ SourceView::MarkerView::_UpdateIPMarkers()
if (fSourceCode != NULL && fStackTrace != NULL) {
LocatableFile* sourceFile = fSourceCode->GetSourceFile();
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker<Team> locker(fTeam);
for (int32 i = 0; StackFrame* frame = fStackTrace->FrameAt(i);
i++) {
target_addr_t ip = frame->InstructionPointer();
FunctionInstance* functionInstance;
Statement* statement;
if (fDebugModel->GetTeam()->GetStatementAtAddress(ip,
if (fTeam->GetStatementAtAddress(ip,
functionInstance, statement) != B_OK) {
continue;
}
@@ -726,11 +725,11 @@ SourceView::MarkerView::_UpdateBreakpointMarkers()
if (fSourceCode != NULL) {
LocatableFile* sourceFile = fSourceCode->GetSourceFile();
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker<Team> locker(fTeam);
// get the breakpoints in our source code range
BObjectList<UserBreakpoint> breakpoints;
fDebugModel->GetBreakpointsForSourceCode(fSourceCode, breakpoints);
fTeam->GetBreakpointsForSourceCode(fSourceCode, breakpoints);
for (int32 i = 0; UserBreakpoint* breakpoint = breakpoints.ItemAt(i);
i++) {
@@ -738,7 +737,7 @@ SourceView::MarkerView::_UpdateBreakpointMarkers()
= breakpoint->InstanceAt(0);
FunctionInstance* functionInstance;
Statement* statement;
if (fDebugModel->GetTeam()->GetStatementAtAddress(
if (fTeam->GetStatementAtAddress(
breakpointInstance->Address(), functionInstance,
statement) != B_OK) {
continue;
@@ -1402,10 +1401,10 @@ SourceView::TextView::_ScrollToBottom(void)
// #pragma mark - SourceView
SourceView::SourceView(TeamDebugModel* debugModel, Listener* listener)
SourceView::SourceView(Team* team, Listener* listener)
:
BView("source view", 0),
fDebugModel(debugModel),
fTeam(team),
fStackTrace(NULL),
fStackFrame(NULL),
fSourceCode(NULL),
@@ -1430,9 +1429,9 @@ SourceView::~SourceView()
/*static*/ SourceView*
SourceView::Create(TeamDebugModel* debugModel, Listener* listener)
SourceView::Create(Team* team, Listener* listener)
{
SourceView* self = new SourceView(debugModel, listener);
SourceView* self = new SourceView(team, listener);
try {
self->_Init();
@@ -1537,11 +1536,11 @@ printf("SourceView::ScrollToAddress(%#llx)\n", address);
if (fSourceCode == NULL)
return false;
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker<Team> locker(fTeam);
FunctionInstance* functionInstance;
Statement* statement;
if (fDebugModel->GetTeam()->GetStatementAtAddress(address, functionInstance,
if (fTeam->GetStatementAtAddress(address, functionInstance,
statement) != B_OK) {
return false;
}
@@ -1649,8 +1648,7 @@ SourceView::DoLayout()
void
SourceView::_Init()
{
AddChild(fMarkerView = new MarkerView(this, fDebugModel, fListener,
&fFontInfo));
AddChild(fMarkerView = new MarkerView(this, fTeam, fListener, &fFontInfo));
AddChild(fTextView = new TextView(this, &fFontInfo));
}
@@ -5,6 +5,7 @@
#ifndef SOURCE_VIEW_H
#define SOURCE_VIEW_H
#include <Font.h>
#include <View.h>
@@ -16,7 +17,7 @@ class SourceCode;
class StackFrame;
class StackTrace;
class Statement;
class TeamDebugModel;
class Team;
class SourceView : public BView {
@@ -24,12 +25,10 @@ public:
class Listener;
public:
SourceView(TeamDebugModel* debugModel,
Listener* listener);
SourceView(Team* team, Listener* listener);
~SourceView();
static SourceView* Create(TeamDebugModel* debugModel,
Listener* listener);
static SourceView* Create(Team* team, Listener* listener);
// throws
void UnsetListener();
@@ -69,7 +68,7 @@ private:
BSize _DataRectSize() const;
private:
TeamDebugModel* fDebugModel;
Team* fTeam;
StackTrace* fStackTrace;
StackFrame* fStackFrame;
SourceCode* fSourceCode;
@@ -21,6 +21,7 @@
#include <AutoLocker.h>
#include "Breakpoint.h"
#include "CpuState.h"
#include "DisassembledCode.h"
#include "FileSourceCode.h"
@@ -43,11 +44,11 @@ enum {
// #pragma mark - TeamWindow
TeamWindow::TeamWindow(TeamDebugModel* debugModel, Listener* listener)
TeamWindow::TeamWindow(::Team* team, Listener* listener)
:
BWindow(BRect(100, 100, 899, 699), "Team", B_TITLED_WINDOW,
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
fDebugModel(debugModel),
fTeam(team),
fActiveThread(NULL),
fActiveImage(NULL),
fActiveStackTrace(NULL),
@@ -69,14 +70,12 @@ TeamWindow::TeamWindow(TeamDebugModel* debugModel, Listener* listener)
fStepIntoButton(NULL),
fStepOutButton(NULL)
{
::Team* team = debugModel->GetTeam();
BString name = team->Name();
if (team->ID() >= 0)
name << " (" << team->ID() << ")";
BString name = fTeam->Name();
if (fTeam->ID() >= 0)
name << " (" << fTeam->ID() << ")";
SetTitle(name.String());
fDebugModel->AddListener(this);
team->AddListener(this);
fTeam->AddListener(this);
}
@@ -89,8 +88,7 @@ TeamWindow::~TeamWindow()
if (fSourceView != NULL)
fSourceView->UnsetListener();
fDebugModel->GetTeam()->RemoveListener(this);
fDebugModel->RemoveListener(this);
fTeam->RemoveListener(this);
_SetActiveSourceCode(NULL);
_SetActiveFunction(NULL);
@@ -102,9 +100,9 @@ TeamWindow::~TeamWindow()
/*static*/ TeamWindow*
TeamWindow::Create(TeamDebugModel* debugModel, Listener* listener)
TeamWindow::Create(::Team* team, Listener* listener)
{
TeamWindow* self = new TeamWindow(debugModel, listener);
TeamWindow* self = new TeamWindow(team, listener);
try {
self->_Init();
@@ -350,7 +348,7 @@ TeamWindow::ImageDebugInfoChanged(const Team::ImageEvent& event)
void
TeamWindow::UserBreakpointChanged(const TeamDebugModel::BreakpointEvent& event)
TeamWindow::UserBreakpointChanged(const Team::BreakpointEvent& event)
{
BMessage message(MSG_USER_BREAKPOINT_CHANGED);
message.AddUInt64("address", event.GetBreakpoint()->Address());
@@ -386,8 +384,6 @@ TeamWindow::StackFrameValueRetrieved(StackFrame* stackFrame, Variable* variable,
void
TeamWindow::_Init()
{
::Team* team = fDebugModel->GetTeam();
BScrollView* sourceScrollView;
BLayoutBuilder::Group<>(this, B_VERTICAL)
@@ -412,15 +408,14 @@ TeamWindow::_Init()
.End();
// add source view
sourceScrollView->SetTarget(fSourceView = SourceView::Create(fDebugModel,
this));
sourceScrollView->SetTarget(fSourceView = SourceView::Create(fTeam, this));
// add threads tab
BSplitView* threadGroup = new BSplitView(B_HORIZONTAL);
threadGroup->SetName("Threads");
fTabView->AddTab(threadGroup);
BLayoutBuilder::Split<>(threadGroup)
.Add(fThreadListView = ThreadListView::Create(team, this))
.Add(fThreadListView = ThreadListView::Create(fTeam, this))
.Add(fStackTraceView = StackTraceView::Create(this));
// add images tab
@@ -428,7 +423,7 @@ TeamWindow::_Init()
imagesGroup->SetName("Images");
fTabView->AddTab(imagesGroup);
BLayoutBuilder::Split<>(imagesGroup)
.Add(fImageListView = ImageListView::Create(team, this))
.Add(fImageListView = ImageListView::Create(fTeam, this))
.Add(fImageFunctionsView = ImageFunctionsView::Create(this));
// add local variables tab
@@ -436,8 +431,7 @@ TeamWindow::_Init()
fLocalsTabView->AddTab(tab);
// add registers tab
tab = fRegistersView = RegistersView::Create(
fDebugModel->GetArchitecture());
tab = fRegistersView = RegistersView::Create(fTeam->GetArchitecture());
fLocalsTabView->AddTab(tab);
fRunButton->SetMessage(new BMessage(MSG_THREAD_RUN));
@@ -465,7 +459,7 @@ TeamWindow::_Init()
menu->AddItem(item);
item->SetTarget(this);
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
_UpdateRunButtons();
}
@@ -484,7 +478,7 @@ TeamWindow::_SetActiveThread(::Thread* thread)
if (fActiveThread != NULL)
fActiveThread->AddReference();
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
_UpdateRunButtons();
StackTrace* stackTrace = fActiveThread != NULL
@@ -512,7 +506,7 @@ TeamWindow::_SetActiveImage(Image* image)
fActiveImage = image;
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
ImageDebugInfo* imageDebugInfo = NULL;
Reference<ImageDebugInfo> imageDebugInfoReference;
@@ -564,7 +558,7 @@ TeamWindow::_SetActiveStackFrame(StackFrame* frame)
return;
if (fActiveStackFrame != NULL) {
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
fActiveStackFrame->RemoveListener(this);
locker.Unlock();
@@ -576,7 +570,7 @@ TeamWindow::_SetActiveStackFrame(StackFrame* frame)
if (fActiveStackFrame != NULL) {
fActiveStackFrame->AddReference();
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
fActiveStackFrame->AddListener(this);
locker.Unlock();
@@ -600,7 +594,7 @@ TeamWindow::_SetActiveFunction(FunctionInstance* functionInstance)
if (functionInstance == fActiveFunction)
return;
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
if (fActiveFunction != NULL) {
fActiveFunction->GetFunction()->RemoveListener(this);
@@ -614,8 +608,7 @@ TeamWindow::_SetActiveFunction(FunctionInstance* functionInstance)
fActiveFunction = NULL;
if (functionInstance != NULL) {
_SetActiveImage(fDebugModel->GetTeam()->ImageByAddress(
functionInstance->Address()));
_SetActiveImage(fTeam->ImageByAddress(functionInstance->Address()));
}
fActiveFunction = functionInstance;
@@ -680,7 +673,7 @@ TeamWindow::_UpdateCpuState()
if (fActiveThread != NULL) {
// Get the CPU state from the active stack frame or the thread directly.
if (fActiveStackFrame == NULL) {
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
cpuState = fActiveThread->GetCpuState();
cpuStateReference.SetTo(cpuState);
locker.Unlock();
@@ -741,9 +734,9 @@ TeamWindow::_ScrollToActiveFunction()
void
TeamWindow::_HandleThreadStateChanged(thread_id threadID)
{
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
::Thread* thread = fDebugModel->GetTeam()->ThreadByID(threadID);
::Thread* thread = fTeam->ThreadByID(threadID);
if (thread == NULL)
return;
@@ -785,7 +778,7 @@ TeamWindow::_HandleStackTraceChanged(thread_id threadID)
if (fActiveThread == NULL || threadID != fActiveThread->ID())
return;
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
StackTrace* stackTrace = fActiveThread != NULL
? fActiveThread->GetStackTrace() : NULL;
@@ -817,7 +810,7 @@ printf("TeamWindow::_HandleImageDebugInfoChanged(%ld)\n", imageID);
if (fActiveImage == NULL || imageID != fActiveImage->ID())
return;
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
ImageDebugInfo* imageDebugInfo = fActiveImage != NULL
? fActiveImage->GetImageDebugInfo() : NULL;
@@ -839,7 +832,7 @@ TeamWindow::_HandleSourceCodeChanged()
return;
// get a reference to the source code
AutoLocker<TeamDebugModel> locker(fDebugModel);
AutoLocker< ::Team> locker(fTeam);
SourceCode* sourceCode = fActiveFunction->GetFunction()->GetSourceCode();
if (sourceCode == NULL)
+5 -12
View File
@@ -16,7 +16,6 @@
#include "StackFrame.h"
#include "StackTraceView.h"
#include "Team.h"
#include "TeamDebugModel.h"
#include "ThreadListView.h"
#include "VariablesView.h"
@@ -34,18 +33,15 @@ class VariablesView;
class TeamWindow : public BWindow, ThreadListView::Listener,
ImageListView::Listener, StackTraceView::Listener,
ImageFunctionsView::Listener, SourceView::Listener, VariablesView::Listener,
Team::Listener, TeamDebugModel::Listener, Function::Listener,
StackFrame::Listener {
Team::Listener, Function::Listener, StackFrame::Listener {
public:
class Listener;
public:
TeamWindow(TeamDebugModel* debugModel,
Listener* listener);
TeamWindow(::Team* team, Listener* listener);
~TeamWindow();
static TeamWindow* Create(TeamDebugModel* debugModel,
Listener* listener);
static TeamWindow* Create(::Team* team, Listener* listener);
// throws
virtual void DispatchMessage(BMessage* message,
@@ -86,11 +82,8 @@ private:
const Team::ThreadEvent& event);
virtual void ImageDebugInfoChanged(
const Team::ImageEvent& event);
// TeamDebugModel::Listener
virtual void UserBreakpointChanged(
const TeamDebugModel::BreakpointEvent&
event);
const Team::BreakpointEvent& event);
// Function::Listener
virtual void FunctionSourceCodeChanged(Function* function);
@@ -124,7 +117,7 @@ private:
target_addr_t address);
private:
TeamDebugModel* fDebugModel;
::Team* fTeam;
::Thread* fActiveThread;
Image* fActiveImage;
StackTrace* fActiveStackTrace;
+196 -2
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License.
*/
#include "Team.h"
#include <stdio.h>
@@ -11,21 +12,50 @@
#include <AutoLocker.h>
#include "Breakpoint.h"
#include "DisassembledCode.h"
#include "FileSourceCode.h"
#include "Function.h"
#include "ImageDebugInfo.h"
#include "SourceCode.h"
#include "SpecificImageDebugInfo.h"
#include "Statement.h"
#include "TeamDebugInfo.h"
#include "UserBreakpoint.h"
// #pragma mark - BreakpointByAddressPredicate
struct Team::BreakpointByAddressPredicate
: UnaryPredicate<Breakpoint> {
BreakpointByAddressPredicate(target_addr_t address)
:
fAddress(address)
{
}
virtual int operator()(const Breakpoint* breakpoint) const
{
return -Breakpoint::CompareAddressBreakpoint(&fAddress, breakpoint);
}
private:
target_addr_t fAddress;
};
// #pragma mark - Team
Team::Team(team_id teamID, TeamDebugInfo* debugInfo)
Team::Team(team_id teamID, TeamMemory* teamMemory, Architecture* architecture,
TeamDebugInfo* debugInfo)
:
fLock("team lock"),
fID(teamID),
fTeamMemory(teamMemory),
fArchitecture(architecture),
fDebugInfo(debugInfo)
{
fDebugInfo->AddReference();
@@ -34,6 +64,9 @@ Team::Team(team_id teamID, TeamDebugInfo* debugInfo)
Team::~Team()
{
for (int32 i = 0; Breakpoint* breakpoint = fBreakpoints.ItemAt(i); i++)
breakpoint->RemoveReference();
while (Image* image = fImages.RemoveHead())
image->RemoveReference();
@@ -47,7 +80,7 @@ Team::~Team()
status_t
Team::Init()
{
return BLocker::InitCheck();
return fLock.InitCheck();
}
@@ -209,6 +242,104 @@ Team::Images() const
}
bool
Team::AddBreakpoint(Breakpoint* breakpoint)
{
if (fBreakpoints.BinaryInsert(breakpoint, &Breakpoint::CompareBreakpoints))
return true;
breakpoint->RemoveReference();
return false;
}
void
Team::RemoveBreakpoint(Breakpoint* breakpoint)
{
int32 index = fBreakpoints.BinarySearchIndex(*breakpoint,
&Breakpoint::CompareBreakpoints);
if (index < 0)
return;
fBreakpoints.RemoveItemAt(index);
breakpoint->RemoveReference();
}
int32
Team::CountBreakpoints() const
{
return fBreakpoints.CountItems();
}
Breakpoint*
Team::BreakpointAt(int32 index) const
{
return fBreakpoints.ItemAt(index);
}
Breakpoint*
Team::BreakpointAtAddress(target_addr_t address) const
{
return fBreakpoints.BinarySearchByKey(address,
&Breakpoint::CompareAddressBreakpoint);
}
void
Team::GetBreakpointsInAddressRange(TargetAddressRange range,
BObjectList<UserBreakpoint>& breakpoints) const
{
int32 index = fBreakpoints.FindBinaryInsertionIndex(
BreakpointByAddressPredicate(range.Start()));
for (; Breakpoint* breakpoint = fBreakpoints.ItemAt(index); index++) {
if (breakpoint->Address() > range.End())
break;
for (UserBreakpointInstanceList::ConstIterator it
= breakpoint->UserBreakpoints().GetIterator();
UserBreakpointInstance* instance = it.Next();) {
breakpoints.AddItem(instance->GetUserBreakpoint());
}
}
// TODO: Avoid duplicates!
}
void
Team::GetBreakpointsForSourceCode(SourceCode* sourceCode,
BObjectList<UserBreakpoint>& breakpoints) const
{
if (DisassembledCode* disassembledCode
= dynamic_cast<DisassembledCode*>(sourceCode)) {
GetBreakpointsInAddressRange(disassembledCode->StatementAddressRange(),
breakpoints);
return;
}
LocatableFile* sourceFile = sourceCode->GetSourceFile();
if (sourceFile == NULL)
return;
// TODO: This can probably be optimized. Maybe by registering the user
// breakpoints with the team and sorting them by source code.
for (int32 i = 0; Breakpoint* breakpoint = fBreakpoints.ItemAt(i); i++) {
UserBreakpointInstance* userBreakpointInstance
= breakpoint->FirstUserBreakpoint();
if (userBreakpointInstance == NULL)
continue;
UserBreakpoint* userBreakpoint
= userBreakpointInstance->GetUserBreakpoint();
if (userBreakpoint->GetFunction()->SourceFile() == sourceFile)
breakpoints.AddItem(userBreakpoint);
}
}
status_t
Team::GetStatementAtAddress(target_addr_t address, FunctionInstance*& _function,
Statement*& _statement)
@@ -369,6 +500,17 @@ Team::NotifyImageDebugInfoChanged(Image* image)
}
void
Team::NotifyUserBreakpointChanged(Breakpoint* breakpoint)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->UserBreakpointChanged(BreakpointEvent(
TEAM_EVENT_USER_BREAKPOINT_CHANGED, this, breakpoint));
}
}
void
Team::_NotifyThreadAdded(Thread* thread)
{
@@ -409,6 +551,28 @@ Team::_NotifyImageRemoved(Image* image)
}
void
Team::_NotifyBreakpointAdded(Breakpoint* breakpoint)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->BreakpointAdded(BreakpointEvent(
TEAM_EVENT_BREAKPOINT_ADDED, this, breakpoint));
}
}
void
Team::_NotifyBreakpointRemoved(Breakpoint* breakpoint)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->BreakpointRemoved(BreakpointEvent(
TEAM_EVENT_BREAKPOINT_REMOVED, this, breakpoint));
}
}
// #pragma mark - Event
@@ -442,6 +606,18 @@ Team::ImageEvent::ImageEvent(uint32 type, Image* image)
}
// #pragma mark - BreakpointEvent
Team::BreakpointEvent::BreakpointEvent(uint32 type, Team* team,
Breakpoint* breakpoint)
:
Event(type, team),
fBreakpoint(breakpoint)
{
}
// #pragma mark - Listener
@@ -496,3 +672,21 @@ void
Team::Listener::ImageDebugInfoChanged(const Team::ImageEvent& event)
{
}
void
Team::Listener::BreakpointAdded(const Team::BreakpointEvent& event)
{
}
void
Team::Listener::BreakpointRemoved(const Team::BreakpointEvent& event)
{
}
void
Team::Listener::UserBreakpointChanged(const Team::BreakpointEvent& event)
{
}
+76 -3
View File
@@ -5,10 +5,14 @@
#ifndef TEAM_H
#define TEAM_H
#include <Locker.h>
#include <ObjectList.h>
#include "Image.h"
#include "ImageInfo.h"
#include "TargetAddressRange.h"
#include "Thread.h"
#include "ThreadInfo.h"
@@ -24,32 +28,51 @@ enum {
TEAM_EVENT_THREAD_CPU_STATE_CHANGED,
TEAM_EVENT_THREAD_STACK_TRACE_CHANGED,
TEAM_EVENT_IMAGE_DEBUG_INFO_CHANGED
TEAM_EVENT_IMAGE_DEBUG_INFO_CHANGED,
TEAM_EVENT_BREAKPOINT_ADDED,
TEAM_EVENT_BREAKPOINT_REMOVED,
TEAM_EVENT_USER_BREAKPOINT_CHANGED
};
class Architecture;
class Breakpoint;
class FunctionID;
class FunctionInstance;
class LocatableFile;
class SourceCode;
class SourceLocation;
class Statement;
class TeamDebugInfo;
class TeamMemory;
class UserBreakpoint;
class Team : public BLocker {
class Team {
public:
class Event;
class ThreadEvent;
class ImageEvent;
class BreakpointEvent;
class Listener;
public:
Team(team_id teamID, TeamDebugInfo* debugInfo);
Team(team_id teamID, TeamMemory* teamMemory,
Architecture* architecture,
TeamDebugInfo* debugInfo);
~Team();
status_t Init();
bool Lock() { return fLock.Lock(); }
void Unlock() { fLock.Unlock(); }
team_id ID() const { return fID; }
TeamMemory* GetTeamMemory() const
{ return fTeamMemory; }
Architecture* GetArchitecture() const
{ return fArchitecture; }
TeamDebugInfo* DebugInfo() const { return fDebugInfo; }
const char* Name() const { return fName.String(); }
@@ -72,6 +95,23 @@ public:
Image* ImageByAddress(target_addr_t address) const;
const ImageList& Images() const;
bool AddBreakpoint(Breakpoint* breakpoint);
// takes over reference (also on error)
void RemoveBreakpoint(Breakpoint* breakpoint);
// releases its own reference
int32 CountBreakpoints() const;
Breakpoint* BreakpointAt(int32 index) const;
Breakpoint* BreakpointAtAddress(
target_addr_t address) const;
void GetBreakpointsInAddressRange(
TargetAddressRange range,
BObjectList<UserBreakpoint>& breakpoints)
const;
void GetBreakpointsForSourceCode(
SourceCode* sourceCode,
BObjectList<UserBreakpoint>& breakpoints)
const;
status_t GetStatementAtAddress(target_addr_t address,
FunctionInstance*& _function,
Statement*& _statement);
@@ -97,7 +137,14 @@ public:
// service methods for Image
void NotifyImageDebugInfoChanged(Image* image);
// breakpoint related service methods
void NotifyUserBreakpointChanged(
Breakpoint* breakpoint);
private:
struct BreakpointByAddressPredicate;
typedef BObjectList<Breakpoint> BreakpointList;
typedef DoublyLinkedList<Listener> ListenerList;
private:
@@ -105,13 +152,20 @@ private:
void _NotifyThreadRemoved(Thread* thread);
void _NotifyImageAdded(Image* image);
void _NotifyImageRemoved(Image* image);
void _NotifyBreakpointAdded(Breakpoint* breakpoint);
void _NotifyBreakpointRemoved(
Breakpoint* breakpoint);
private:
BLocker fLock;
team_id fID;
TeamMemory* fTeamMemory;
Architecture* fArchitecture;
TeamDebugInfo* fDebugInfo;
BString fName;
ThreadList fThreads;
ImageList fImages;
BreakpointList fBreakpoints;
ListenerList fListeners;
};
@@ -151,6 +205,18 @@ protected:
};
class Team::BreakpointEvent : public Event {
public:
BreakpointEvent(uint32 type, Team* team,
Breakpoint* breakpoint);
Breakpoint* GetBreakpoint() const { return fBreakpoint; }
protected:
Breakpoint* fBreakpoint;
};
class Team::Listener : public DoublyLinkedListLinkImpl<Team::Listener> {
public:
virtual ~Listener();
@@ -170,6 +236,13 @@ public:
virtual void ImageDebugInfoChanged(
const Team::ImageEvent& event);
virtual void BreakpointAdded(
const Team::BreakpointEvent& event);
virtual void BreakpointRemoved(
const Team::BreakpointEvent& event);
virtual void UserBreakpointChanged(
const Team::BreakpointEvent& event);
};
-264
View File
@@ -1,264 +0,0 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "TeamDebugModel.h"
#include <new>
#include <AutoLocker.h>
#include "Breakpoint.h"
#include "DisassembledCode.h"
#include "FileSourceCode.h"
#include "Function.h"
#include "UserBreakpoint.h"
// #pragma mark - BreakpointByAddressPredicate
struct TeamDebugModel::BreakpointByAddressPredicate
: UnaryPredicate<Breakpoint> {
BreakpointByAddressPredicate(target_addr_t address)
:
fAddress(address)
{
}
virtual int operator()(const Breakpoint* breakpoint) const
{
return -Breakpoint::CompareAddressBreakpoint(&fAddress, breakpoint);
}
private:
target_addr_t fAddress;
};
// #pragma mark - TeamDebugModel
TeamDebugModel::TeamDebugModel(Team* team, TeamMemory* teamMemory,
Architecture* architecture)
:
fTeam(team),
fTeamMemory(teamMemory),
fArchitecture(architecture)
{
}
TeamDebugModel::~TeamDebugModel()
{
for (int32 i = 0; Breakpoint* breakpoint = fBreakpoints.ItemAt(i); i++)
breakpoint->RemoveReference();
}
status_t
TeamDebugModel::Init()
{
return B_OK;
}
bool
TeamDebugModel::AddBreakpoint(Breakpoint* breakpoint)
{
if (fBreakpoints.BinaryInsert(breakpoint, &Breakpoint::CompareBreakpoints))
return true;
breakpoint->RemoveReference();
return false;
}
void
TeamDebugModel::RemoveBreakpoint(Breakpoint* breakpoint)
{
int32 index = fBreakpoints.BinarySearchIndex(*breakpoint,
&Breakpoint::CompareBreakpoints);
if (index < 0)
return;
fBreakpoints.RemoveItemAt(index);
breakpoint->RemoveReference();
}
int32
TeamDebugModel::CountBreakpoints() const
{
return fBreakpoints.CountItems();
}
Breakpoint*
TeamDebugModel::BreakpointAt(int32 index) const
{
return fBreakpoints.ItemAt(index);
}
Breakpoint*
TeamDebugModel::BreakpointAtAddress(target_addr_t address) const
{
return fBreakpoints.BinarySearchByKey(address,
&Breakpoint::CompareAddressBreakpoint);
}
void
TeamDebugModel::GetBreakpointsInAddressRange(TargetAddressRange range,
BObjectList<UserBreakpoint>& breakpoints) const
{
int32 index = fBreakpoints.FindBinaryInsertionIndex(
BreakpointByAddressPredicate(range.Start()));
for (; Breakpoint* breakpoint = fBreakpoints.ItemAt(index); index++) {
if (breakpoint->Address() > range.End())
break;
for (UserBreakpointInstanceList::ConstIterator it
= breakpoint->UserBreakpoints().GetIterator();
UserBreakpointInstance* instance = it.Next();) {
breakpoints.AddItem(instance->GetUserBreakpoint());
}
}
// TODO: Avoid duplicates!
}
void
TeamDebugModel::GetBreakpointsForSourceCode(SourceCode* sourceCode,
BObjectList<UserBreakpoint>& breakpoints) const
{
if (DisassembledCode* disassembledCode
= dynamic_cast<DisassembledCode*>(sourceCode)) {
GetBreakpointsInAddressRange(disassembledCode->StatementAddressRange(),
breakpoints);
return;
}
LocatableFile* sourceFile = sourceCode->GetSourceFile();
if (sourceFile == NULL)
return;
// TODO: This can probably be optimized. Maybe by registering the user
// breakpoints with the team debug model and sorting them by source code.
for (int32 i = 0; Breakpoint* breakpoint = fBreakpoints.ItemAt(i); i++) {
UserBreakpointInstance* userBreakpointInstance
= breakpoint->FirstUserBreakpoint();
if (userBreakpointInstance == NULL)
continue;
UserBreakpoint* userBreakpoint
= userBreakpointInstance->GetUserBreakpoint();
if (userBreakpoint->GetFunction()->SourceFile() == sourceFile)
breakpoints.AddItem(userBreakpoint);
}
}
void
TeamDebugModel::AddListener(Listener* listener)
{
AutoLocker<TeamDebugModel> locker(this);
fListeners.Add(listener);
}
void
TeamDebugModel::RemoveListener(Listener* listener)
{
AutoLocker<TeamDebugModel> locker(this);
fListeners.Remove(listener);
}
void
TeamDebugModel::NotifyUserBreakpointChanged(Breakpoint* breakpoint)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->UserBreakpointChanged(BreakpointEvent(
TEAM_DEBUG_MODEL_EVENT_USER_BREAKPOINT_CHANGED, this, breakpoint));
}
}
void
TeamDebugModel::_NotifyBreakpointAdded(Breakpoint* breakpoint)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->BreakpointAdded(BreakpointEvent(
TEAM_DEBUG_MODEL_EVENT_BREAKPOINT_ADDED, this, breakpoint));
}
}
void
TeamDebugModel::_NotifyBreakpointRemoved(Breakpoint* breakpoint)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->BreakpointRemoved(BreakpointEvent(
TEAM_DEBUG_MODEL_EVENT_BREAKPOINT_REMOVED, this, breakpoint));
}
}
// #pragma mark - Event
TeamDebugModel::Event::Event(uint32 type, TeamDebugModel* model)
:
fEventType(type),
fModel(model)
{
}
// #pragma mark - ThreadEvent
TeamDebugModel::BreakpointEvent::BreakpointEvent(uint32 type,
TeamDebugModel* model, Breakpoint* breakpoint)
:
Event(type, model),
fBreakpoint(breakpoint)
{
}
// #pragma mark - Listener
TeamDebugModel::Listener::~Listener()
{
}
void
TeamDebugModel::Listener::BreakpointAdded(
const TeamDebugModel::BreakpointEvent& event)
{
}
void
TeamDebugModel::Listener::BreakpointRemoved(
const TeamDebugModel::BreakpointEvent& event)
{
}
void
TeamDebugModel::Listener::UserBreakpointChanged(
const TeamDebugModel::BreakpointEvent& event)
{
}
-140
View File
@@ -1,140 +0,0 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef TEAM_DEBUG_MODEL_H
#define TEAM_DEBUG_MODEL_H
#include <ObjectList.h>
#include "Breakpoint.h"
#include "TargetAddressRange.h"
#include "Team.h"
// team debug model event types
enum {
TEAM_DEBUG_MODEL_EVENT_BREAKPOINT_ADDED,
TEAM_DEBUG_MODEL_EVENT_BREAKPOINT_REMOVED,
TEAM_DEBUG_MODEL_EVENT_USER_BREAKPOINT_CHANGED
};
class Architecture;
class Breakpoint;
class FunctionID;
class SourceCode;
class TeamMemory;
class UserBreakpoint;
class TeamDebugModel {
public:
class Event;
class BreakpointEvent;
class Listener;
public:
TeamDebugModel(Team* team,
TeamMemory* teamMemory,
Architecture* architecture);
~TeamDebugModel();
status_t Init();
bool Lock() { return fTeam->Lock(); }
void Unlock() { fTeam->Unlock(); }
Team* GetTeam() const { return fTeam; }
TeamMemory* GetTeamMemory() const
{ return fTeamMemory; }
Architecture* GetArchitecture() const
{ return fArchitecture; }
bool AddBreakpoint(Breakpoint* breakpoint);
// takes over reference (also on error)
void RemoveBreakpoint(Breakpoint* breakpoint);
// releases its own reference
int32 CountBreakpoints() const;
Breakpoint* BreakpointAt(int32 index) const;
Breakpoint* BreakpointAtAddress(
target_addr_t address) const;
void GetBreakpointsInAddressRange(
TargetAddressRange range,
BObjectList<UserBreakpoint>& breakpoints)
const;
void GetBreakpointsForSourceCode(
SourceCode* sourceCode,
BObjectList<UserBreakpoint>& breakpoints)
const;
void AddListener(Listener* listener);
void RemoveListener(Listener* listener);
void NotifyUserBreakpointChanged(
Breakpoint* breakpoint);
private:
struct BreakpointByAddressPredicate;
typedef BObjectList<Breakpoint> BreakpointList;
typedef DoublyLinkedList<Listener> ListenerList;
private:
void _NotifyBreakpointAdded(Breakpoint* breakpoint);
void _NotifyBreakpointRemoved(
Breakpoint* breakpoint);
private:
Team* fTeam;
TeamMemory* fTeamMemory;
Architecture* fArchitecture;
BreakpointList fBreakpoints;
ListenerList fListeners;
};
class TeamDebugModel::Event {
public:
Event(uint32 type, TeamDebugModel* model);
uint32 EventType() const { return fEventType; }
TeamDebugModel* Model() const { return fModel; }
protected:
uint32 fEventType;
TeamDebugModel* fModel;
};
class TeamDebugModel::BreakpointEvent : public Event {
public:
BreakpointEvent(uint32 type,
TeamDebugModel* model,
Breakpoint* breakpoint);
Breakpoint* GetBreakpoint() const { return fBreakpoint; }
protected:
Breakpoint* fBreakpoint;
};
class TeamDebugModel::Listener
: public DoublyLinkedListLinkImpl<TeamDebugModel::Listener> {
public:
virtual ~Listener();
virtual void BreakpointAdded(
const TeamDebugModel::BreakpointEvent&
event);
virtual void BreakpointRemoved(
const TeamDebugModel::BreakpointEvent&
event);
virtual void UserBreakpointChanged(
const TeamDebugModel::BreakpointEvent&
event);
};
#endif // TEAM_DEBUG_MODEL_H