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