From a5e1e7ceba589daa8322d42af96077aaa94a7232 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 22 Jul 2009 19:20:06 +0000 Subject: [PATCH] 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 --- src/apps/debugger/BreakpointManager.cpp | 68 ++--- src/apps/debugger/BreakpointManager.h | 6 +- src/apps/debugger/Jamfile | 1 - src/apps/debugger/Jobs.cpp | 10 +- src/apps/debugger/Jobs.h | 3 - src/apps/debugger/TeamDebugger.cpp | 39 +-- src/apps/debugger/TeamDebugger.h | 3 +- src/apps/debugger/ThreadHandler.cpp | 21 +- src/apps/debugger/ThreadHandler.h | 6 +- .../debugger/gui/team_window/SourceView.cpp | 42 ++- .../debugger/gui/team_window/SourceView.h | 11 +- .../debugger/gui/team_window/TeamWindow.cpp | 63 ++--- .../debugger/gui/team_window/TeamWindow.h | 17 +- src/apps/debugger/model/Team.cpp | 198 ++++++++++++- src/apps/debugger/model/Team.h | 79 +++++- src/apps/debugger/model/TeamDebugModel.cpp | 264 ------------------ src/apps/debugger/model/TeamDebugModel.h | 140 ---------- 17 files changed, 398 insertions(+), 573 deletions(-) delete mode 100644 src/apps/debugger/model/TeamDebugModel.cpp delete mode 100644 src/apps/debugger/model/TeamDebugModel.h diff --git a/src/apps/debugger/BreakpointManager.cpp b/src/apps/debugger/BreakpointManager.cpp index 901611f58a..4a03389374 100644 --- a/src/apps/debugger/BreakpointManager.cpp +++ b/src/apps/debugger/BreakpointManager.cpp @@ -12,14 +12,14 @@ #include #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 installLocker(fLock); - AutoLocker modelLocker(fDebugModel); + AutoLocker 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 installLocker(fLock); - AutoLocker modelLocker(fDebugModel); + AutoLocker 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 installLocker(fLock); - AutoLocker modelLocker(fDebugModel); + AutoLocker 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 installLocker(fLock); - AutoLocker modelLocker(fDebugModel); + AutoLocker 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 breakpointReference(breakpoint); if (breakpoint->IsUnused()) - fDebugModel->RemoveBreakpoint(breakpoint); + fTeam->RemoveBreakpoint(breakpoint); - modelLocker.Unlock(); + teamLocker.Unlock(); if (uninstall) { fDebuggerInterface->UninstallBreakpoint(address); diff --git a/src/apps/debugger/BreakpointManager.h b/src/apps/debugger/BreakpointManager.h index d0d16e5e69..0f89e2cf8d 100644 --- a/src/apps/debugger/BreakpointManager.h +++ b/src/apps/debugger/BreakpointManager.h @@ -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; }; diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index d90e062ef8..91d8fa6955 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -114,7 +114,6 @@ Application Debugger : SymbolInfo.cpp UserBreakpoint.cpp Team.cpp - TeamDebugModel.cpp TeamMemory.cpp Thread.cpp ThreadInfo.cpp diff --git a/src/apps/debugger/Jobs.cpp b/src/apps/debugger/Jobs.cpp index 6321e2be40..7a3dc8e564 100644 --- a/src/apps/debugger/Jobs.cpp +++ b/src/apps/debugger/Jobs.cpp @@ -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 locker(fDebugModel); + AutoLocker 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 locker(fDebugModel); + AutoLocker locker(fThread->GetTeam()); StackFrameValues* values = fStackFrame->Values(); diff --git a/src/apps/debugger/Jobs.h b/src/apps/debugger/Jobs.h index 6d316cfb0a..3e7587927e 100644 --- a/src/apps/debugger/Jobs.h +++ b/src/apps/debugger/Jobs.h @@ -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; diff --git a/src/apps/debugger/TeamDebugger.cpp b/src/apps/debugger/TeamDebugger.cpp index 246f089120..b0ec1cd3c3 100644 --- a/src/apps/debugger/TeamDebugger.cpp +++ b/src/apps/debugger/TeamDebugger.cpp @@ -3,6 +3,7 @@ * Distributed under the terms of the MIT License. */ + #include "TeamDebugger.h" #include @@ -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 locker(fDebugModel); + AutoLocker< ::Team> locker(fTeam); ThreadHandler* handler = fThreadHandlers.Lookup(threadID); if (handler != NULL) diff --git a/src/apps/debugger/TeamDebugger.h b/src/apps/debugger/TeamDebugger.h index 5803bc6b42..1e47d78f3a 100644 --- a/src/apps/debugger/TeamDebugger.h +++ b/src/apps/debugger/TeamDebugger.h @@ -5,6 +5,7 @@ #ifndef TEAM_DEBUGGER_H #define TEAM_DEBUGGER_H + #include #include @@ -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 diff --git a/src/apps/debugger/ThreadHandler.cpp b/src/apps/debugger/ThreadHandler.cpp index cc74179f99..f00f69e468 100644 --- a/src/apps/debugger/ThreadHandler.cpp +++ b/src/apps/debugger/ThreadHandler.cpp @@ -3,6 +3,7 @@ * Distributed under the terms of the MIT License. */ + #include "ThreadHandler.h" #include @@ -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 locker(fDebugModel); - Breakpoint* breakpoint = fDebugModel->BreakpointAtAddress( + AutoLocker 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 locker(fDebugModel); + AutoLocker locker(fThread->GetTeam()); if (fThread->State() == THREAD_STATE_UNKNOWN) return; @@ -310,7 +309,7 @@ fStepStatement->CoveringAddressRange().End()); void ThreadHandler::HandleThreadStateChanged() { - AutoLocker locker(fDebugModel); + AutoLocker 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 locker(fDebugModel); + AutoLocker 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 locker(fDebugModel); + AutoLocker locker(fThread->GetTeam()); _SetThreadState(THREAD_STATE_STOPPED, cpuState); @@ -389,7 +388,7 @@ ThreadHandler::_SetThreadState(uint32 state, CpuState* cpuState) Statement* ThreadHandler::_GetStatementAtInstructionPointer(StackFrame* frame) { - AutoLocker locker(fDebugModel); + AutoLocker locker(fThread->GetTeam()); FunctionInstance* functionInstance = frame->Function(); if (functionInstance == NULL) diff --git a/src/apps/debugger/ThreadHandler.h b/src/apps/debugger/ThreadHandler.h index 6b85f663e1..6265ac37ab 100644 --- a/src/apps/debugger/ThreadHandler.h +++ b/src/apps/debugger/ThreadHandler.h @@ -5,6 +5,7 @@ #ifndef THREAD_HANDLER_H #define THREAD_HANDLER_H + #include #include @@ -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, 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; diff --git a/src/apps/debugger/gui/team_window/SourceView.cpp b/src/apps/debugger/gui/team_window/SourceView.cpp index a5edf88781..78320a7f62 100644 --- a/src/apps/debugger/gui/team_window/SourceView.cpp +++ b/src/apps/debugger/gui/team_window/SourceView.cpp @@ -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 locker(fDebugModel); + AutoLocker 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 locker(fDebugModel); + AutoLocker 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 locker(fDebugModel); + AutoLocker locker(fTeam); // get the breakpoints in our source code range BObjectList 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 locker(fDebugModel); + AutoLocker 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)); } diff --git a/src/apps/debugger/gui/team_window/SourceView.h b/src/apps/debugger/gui/team_window/SourceView.h index 2a746feba1..e0ac1e5c3b 100644 --- a/src/apps/debugger/gui/team_window/SourceView.h +++ b/src/apps/debugger/gui/team_window/SourceView.h @@ -5,6 +5,7 @@ #ifndef SOURCE_VIEW_H #define SOURCE_VIEW_H + #include #include @@ -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; diff --git a/src/apps/debugger/gui/team_window/TeamWindow.cpp b/src/apps/debugger/gui/team_window/TeamWindow.cpp index ee1f52adcd..eb41e39622 100644 --- a/src/apps/debugger/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/gui/team_window/TeamWindow.cpp @@ -21,6 +21,7 @@ #include +#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 locker(fDebugModel); + AutoLocker< ::Team> locker(fTeam); _UpdateRunButtons(); } @@ -484,7 +478,7 @@ TeamWindow::_SetActiveThread(::Thread* thread) if (fActiveThread != NULL) fActiveThread->AddReference(); - AutoLocker locker(fDebugModel); + AutoLocker< ::Team> locker(fTeam); _UpdateRunButtons(); StackTrace* stackTrace = fActiveThread != NULL @@ -512,7 +506,7 @@ TeamWindow::_SetActiveImage(Image* image) fActiveImage = image; - AutoLocker locker(fDebugModel); + AutoLocker< ::Team> locker(fTeam); ImageDebugInfo* imageDebugInfo = NULL; Reference imageDebugInfoReference; @@ -564,7 +558,7 @@ TeamWindow::_SetActiveStackFrame(StackFrame* frame) return; if (fActiveStackFrame != NULL) { - AutoLocker 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 locker(fDebugModel); + AutoLocker< ::Team> locker(fTeam); fActiveStackFrame->AddListener(this); locker.Unlock(); @@ -600,7 +594,7 @@ TeamWindow::_SetActiveFunction(FunctionInstance* functionInstance) if (functionInstance == fActiveFunction) return; - AutoLocker 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 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 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 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 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 locker(fDebugModel); + AutoLocker< ::Team> locker(fTeam); SourceCode* sourceCode = fActiveFunction->GetFunction()->GetSourceCode(); if (sourceCode == NULL) diff --git a/src/apps/debugger/gui/team_window/TeamWindow.h b/src/apps/debugger/gui/team_window/TeamWindow.h index c232373754..fb0d25ce9c 100644 --- a/src/apps/debugger/gui/team_window/TeamWindow.h +++ b/src/apps/debugger/gui/team_window/TeamWindow.h @@ -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; diff --git a/src/apps/debugger/model/Team.cpp b/src/apps/debugger/model/Team.cpp index 55537e52c8..08c588440b 100644 --- a/src/apps/debugger/model/Team.cpp +++ b/src/apps/debugger/model/Team.cpp @@ -3,6 +3,7 @@ * Distributed under the terms of the MIT License. */ + #include "Team.h" #include @@ -11,21 +12,50 @@ #include +#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 { + 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& 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& breakpoints) const +{ + if (DisassembledCode* disassembledCode + = dynamic_cast(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) +{ +} diff --git a/src/apps/debugger/model/Team.h b/src/apps/debugger/model/Team.h index 80819e5276..d98703eae2 100644 --- a/src/apps/debugger/model/Team.h +++ b/src/apps/debugger/model/Team.h @@ -5,10 +5,14 @@ #ifndef TEAM_H #define TEAM_H + #include +#include + #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& breakpoints) + const; + void GetBreakpointsForSourceCode( + SourceCode* sourceCode, + BObjectList& 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 BreakpointList; typedef DoublyLinkedList 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 { 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); }; diff --git a/src/apps/debugger/model/TeamDebugModel.cpp b/src/apps/debugger/model/TeamDebugModel.cpp deleted file mode 100644 index e6607bf30a..0000000000 --- a/src/apps/debugger/model/TeamDebugModel.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Distributed under the terms of the MIT License. - */ - -#include "TeamDebugModel.h" - -#include - -#include - -#include "Breakpoint.h" -#include "DisassembledCode.h" -#include "FileSourceCode.h" -#include "Function.h" -#include "UserBreakpoint.h" - - -// #pragma mark - BreakpointByAddressPredicate - - -struct TeamDebugModel::BreakpointByAddressPredicate - : UnaryPredicate { - 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& 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& breakpoints) const -{ - if (DisassembledCode* disassembledCode - = dynamic_cast(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 locker(this); - fListeners.Add(listener); -} - - -void -TeamDebugModel::RemoveListener(Listener* listener) -{ - AutoLocker 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) -{ -} diff --git a/src/apps/debugger/model/TeamDebugModel.h b/src/apps/debugger/model/TeamDebugModel.h deleted file mode 100644 index 2785b7e561..0000000000 --- a/src/apps/debugger/model/TeamDebugModel.h +++ /dev/null @@ -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 - -#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& breakpoints) - const; - void GetBreakpointsForSourceCode( - SourceCode* sourceCode, - BObjectList& breakpoints) - const; - - void AddListener(Listener* listener); - void RemoveListener(Listener* listener); - - void NotifyUserBreakpointChanged( - Breakpoint* breakpoint); - -private: - struct BreakpointByAddressPredicate; - - typedef BObjectList BreakpointList; - typedef DoublyLinkedList 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 { -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