Start adding the underlying infrastructure for watchpoint support.
This commit is contained in:
parent
cb51c20c26
commit
601538f2af
@ -61,6 +61,7 @@ Application Debugger :
|
||||
TeamMemoryBlockManager.cpp
|
||||
TeamDebugger.cpp
|
||||
ThreadHandler.cpp
|
||||
WatchpointManager.cpp
|
||||
Worker.cpp
|
||||
|
||||
# arch
|
||||
@ -140,6 +141,7 @@ Application Debugger :
|
||||
TypeComponentPath.cpp
|
||||
TypeLookupConstraints.cpp
|
||||
Variable.cpp
|
||||
Watchpoint.cpp
|
||||
|
||||
# settings
|
||||
BreakpointSetting.cpp
|
||||
@ -148,6 +150,7 @@ Application Debugger :
|
||||
TeamSettings.cpp
|
||||
TeamUiSettings.cpp
|
||||
TeamUiSettingsFactory.cpp
|
||||
WatchpointSetting.cpp
|
||||
|
||||
# settings/generic
|
||||
Setting.cpp
|
||||
|
@ -16,6 +16,10 @@ enum {
|
||||
MSG_CLEAR_BREAKPOINT = 'cbrk',
|
||||
MSG_ENABLE_BREAKPOINT = 'ebrk',
|
||||
MSG_DISABLE_BREAKPOINT = 'dbrk',
|
||||
MSG_SET_WATCHPOINT = 'swpt',
|
||||
MSG_CLEAR_WATCHPOINT = 'cwpt',
|
||||
MSG_ENABLE_WATCHPOINT = 'ewpt',
|
||||
MSG_DISABLE_WATCHPOINT = 'dwpt',
|
||||
|
||||
MSG_THREAD_STATE_CHANGED = 'tsch',
|
||||
MSG_THREAD_CPU_STATE_CHANGED = 'tcsc',
|
||||
|
@ -45,6 +45,8 @@
|
||||
#include "ValueNode.h"
|
||||
#include "ValueNodeContainer.h"
|
||||
#include "Variable.h"
|
||||
#include "WatchpointManager.h"
|
||||
#include "WatchpointSetting.h"
|
||||
|
||||
// #pragma mark - ImageHandler
|
||||
|
||||
@ -142,6 +144,7 @@ TeamDebugger::TeamDebugger(Listener* listener, UserInterface* userInterface,
|
||||
fFileManager(NULL),
|
||||
fWorker(NULL),
|
||||
fBreakpointManager(NULL),
|
||||
fWatchpointManager(NULL),
|
||||
fMemoryBlockManager(NULL),
|
||||
fDebugEventListener(-1),
|
||||
fUserInterface(userInterface),
|
||||
@ -199,6 +202,7 @@ TeamDebugger::~TeamDebugger()
|
||||
delete fImageHandlers;
|
||||
|
||||
delete fBreakpointManager;
|
||||
delete fWatchpointManager;
|
||||
delete fMemoryBlockManager;
|
||||
delete fWorker;
|
||||
delete fTeam;
|
||||
@ -304,6 +308,16 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// create the watchpoint manager
|
||||
fWatchpointManager = new(std::nothrow) WatchpointManager(fTeam,
|
||||
fDebuggerInterface);
|
||||
if (fWatchpointManager == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
error = fWatchpointManager->Init();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// create the memory block manager
|
||||
fMemoryBlockManager = new(std::nothrow) TeamMemoryBlockManager();
|
||||
if (fMemoryBlockManager == NULL)
|
||||
@ -465,6 +479,46 @@ TeamDebugger::MessageReceived(BMessage* message)
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_SET_WATCHPOINT:
|
||||
case MSG_CLEAR_WATCHPOINT:
|
||||
{
|
||||
Watchpoint* watchpoint = NULL;
|
||||
BReference<Watchpoint> watchpointReference;
|
||||
uint64 address = 0;
|
||||
uint32 type = 0;
|
||||
int32 length = 0;
|
||||
|
||||
if (message->FindPointer("watchpoint", (void**)&watchpoint)
|
||||
== B_OK) {
|
||||
watchpointReference.SetTo(watchpoint, true);
|
||||
} else if (message->FindUInt64("address", &address) != B_OK)
|
||||
break;
|
||||
|
||||
if (message->what == MSG_SET_WATCHPOINT) {
|
||||
if (watchpoint == NULL && (message->FindUInt32("type", &type)
|
||||
!= B_OK
|
||||
|| message->FindInt32("length", &length) != B_OK)) {
|
||||
break;
|
||||
}
|
||||
|
||||
bool enabled;
|
||||
if (message->FindBool("enabled", &enabled) != B_OK)
|
||||
enabled = true;
|
||||
|
||||
if (watchpoint != NULL)
|
||||
_HandleSetWatchpoint(watchpoint, enabled);
|
||||
else
|
||||
_HandleSetWatchpoint(address, type, length, enabled);
|
||||
} else {
|
||||
if (watchpoint != NULL)
|
||||
_HandleClearWatchpoint(watchpoint);
|
||||
else
|
||||
_HandleClearWatchpoint(address);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_INSPECT_ADDRESS:
|
||||
{
|
||||
TeamMemoryBlock::Listener* listener;
|
||||
@ -696,6 +750,54 @@ TeamDebugger::ClearBreakpointRequested(UserBreakpoint* breakpoint)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::SetWatchpointRequested(target_addr_t address, uint32 type,
|
||||
int32 length, bool enabled)
|
||||
{
|
||||
BMessage message(MSG_SET_WATCHPOINT);
|
||||
message.AddUInt64("address", (uint64)address);
|
||||
message.AddUInt32("type", type);
|
||||
message.AddInt32("length", length);
|
||||
message.AddBool("enabled", enabled);
|
||||
PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::SetWatchpointEnabledRequested(Watchpoint* watchpoint,
|
||||
bool enabled)
|
||||
{
|
||||
BMessage message(MSG_SET_WATCHPOINT);
|
||||
BReference<Watchpoint> watchpointReference(watchpoint);
|
||||
if (message.AddPointer("watchpoint", watchpoint) == B_OK
|
||||
&& message.AddBool("enabled", enabled) == B_OK
|
||||
&& PostMessage(&message) == B_OK) {
|
||||
watchpointReference.Detach();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::ClearWatchpointRequested(target_addr_t address)
|
||||
{
|
||||
BMessage message(MSG_CLEAR_WATCHPOINT);
|
||||
message.AddUInt64("address", (uint64)address);
|
||||
PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::ClearWatchpointRequested(Watchpoint* watchpoint)
|
||||
{
|
||||
BMessage message(MSG_CLEAR_WATCHPOINT);
|
||||
BReference<Watchpoint> watchpointReference(watchpoint);
|
||||
if (message.AddPointer("watchpoint", watchpoint) == B_OK
|
||||
&& PostMessage(&message) == B_OK) {
|
||||
watchpointReference.Detach();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::InspectRequested(target_addr_t address,
|
||||
TeamMemoryBlock::Listener *listener)
|
||||
@ -1309,6 +1411,59 @@ TeamDebugger::_HandleClearUserBreakpoint(UserBreakpoint* breakpoint)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::_HandleSetWatchpoint(target_addr_t address, uint32 type,
|
||||
int32 length, bool enabled)
|
||||
{
|
||||
Watchpoint* watchpoint = new(std::nothrow) Watchpoint(address, type,
|
||||
length);
|
||||
|
||||
if (watchpoint == NULL)
|
||||
return;
|
||||
BReference<Watchpoint> watchpointRef(watchpoint, true);
|
||||
|
||||
_HandleSetWatchpoint(watchpoint, enabled);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::_HandleSetWatchpoint(Watchpoint* watchpoint, bool enabled)
|
||||
{
|
||||
status_t error = fWatchpointManager->InstallWatchpoint(watchpoint,
|
||||
enabled);
|
||||
if (error != B_OK) {
|
||||
_NotifyUser("Install Watchpoint", "Failed to install watchpoint: %s",
|
||||
strerror(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::_HandleClearWatchpoint(target_addr_t address)
|
||||
{
|
||||
TRACE_CONTROL("TeamDebugger::_HandleClearWatchpoint(%#" B_PRIx64 ")\n",
|
||||
address);
|
||||
|
||||
AutoLocker< ::Team> locker(fTeam);
|
||||
|
||||
Watchpoint* watchpoint = fTeam->WatchpointAtAddress(address);
|
||||
if (watchpoint == NULL)
|
||||
return;
|
||||
BReference<Watchpoint> watchpointReference(watchpoint);
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
_HandleClearWatchpoint(watchpoint);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::_HandleClearWatchpoint(Watchpoint* watchpoint)
|
||||
{
|
||||
fWatchpointManager->UninstallWatchpoint(watchpoint);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::_HandleInspectAddress(target_addr_t address,
|
||||
TeamMemoryBlock::Listener* listener)
|
||||
@ -1428,6 +1583,21 @@ TeamDebugger::_LoadSettings()
|
||||
breakpointSetting->IsEnabled());
|
||||
}
|
||||
|
||||
// create the saved watchpoints;
|
||||
for (int32 i = 0; const WatchpointSetting* watchpointSetting
|
||||
= fTeamSettings.WatchpointAt(i); i++) {
|
||||
Watchpoint* watchpoint = new(std::nothrow) Watchpoint(
|
||||
watchpointSetting->Address(), watchpointSetting->Type(),
|
||||
watchpointSetting->Length());
|
||||
if (watchpoint == NULL)
|
||||
return;
|
||||
BReference<Watchpoint> watchpointReference(watchpoint, true);
|
||||
|
||||
// install it
|
||||
fWatchpointManager->InstallWatchpoint(watchpoint,
|
||||
watchpointSetting->IsEnabled());
|
||||
}
|
||||
|
||||
const TeamUiSettings* uiSettings = fTeamSettings.UiSettingFor(
|
||||
fUserInterface->ID());
|
||||
if (uiSettings != NULL)
|
||||
|
@ -24,6 +24,7 @@ class FileManager;
|
||||
class SettingsManager;
|
||||
class TeamDebugInfo;
|
||||
class TeamMemoryBlockManager;
|
||||
class WatchpointManager;
|
||||
|
||||
|
||||
class TeamDebugger : public BLooper, private UserInterfaceListener,
|
||||
@ -67,6 +68,14 @@ private:
|
||||
virtual void ClearBreakpointRequested(target_addr_t address);
|
||||
virtual void ClearBreakpointRequested(
|
||||
UserBreakpoint* breakpoint);
|
||||
virtual void SetWatchpointRequested(target_addr_t address,
|
||||
uint32 type, int32 length, bool enabled);
|
||||
virtual void SetWatchpointEnabledRequested(
|
||||
Watchpoint *watchpoint, bool enabled);
|
||||
virtual void ClearWatchpointRequested(target_addr_t address);
|
||||
virtual void ClearWatchpointRequested(
|
||||
Watchpoint* breakpoint);
|
||||
|
||||
virtual void InspectRequested(target_addr_t address,
|
||||
TeamMemoryBlock::Listener* listener);
|
||||
virtual bool UserInterfaceQuitRequested(
|
||||
@ -123,6 +132,13 @@ private:
|
||||
void _HandleClearUserBreakpoint(
|
||||
UserBreakpoint* breakpoint);
|
||||
|
||||
void _HandleSetWatchpoint(target_addr_t address,
|
||||
uint32 type, int32 length, bool enabled);
|
||||
void _HandleSetWatchpoint(
|
||||
Watchpoint* watchpoint, bool enabled);
|
||||
void _HandleClearWatchpoint( target_addr_t address);
|
||||
void _HandleClearWatchpoint(Watchpoint* watchpoint);
|
||||
|
||||
void _HandleInspectAddress(
|
||||
target_addr_t address,
|
||||
TeamMemoryBlock::Listener* listener);
|
||||
@ -151,6 +167,7 @@ private:
|
||||
FileManager* fFileManager;
|
||||
Worker* fWorker;
|
||||
BreakpointManager* fBreakpointManager;
|
||||
WatchpointManager* fWatchpointManager;
|
||||
TeamMemoryBlockManager*
|
||||
fMemoryBlockManager;
|
||||
thread_id fDebugEventListener;
|
||||
|
95
src/apps/debugger/WatchpointManager.cpp
Normal file
95
src/apps/debugger/WatchpointManager.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2012, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "WatchpointManager.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <AutoLocker.h>
|
||||
|
||||
#include "DebuggerInterface.h"
|
||||
#include "Team.h"
|
||||
#include "Tracing.h"
|
||||
|
||||
|
||||
WatchpointManager::WatchpointManager(Team* team,
|
||||
DebuggerInterface* debuggerInterface)
|
||||
:
|
||||
fLock("watchpoint manager"),
|
||||
fTeam(team),
|
||||
fDebuggerInterface(debuggerInterface)
|
||||
{
|
||||
fDebuggerInterface->AcquireReference();
|
||||
}
|
||||
|
||||
|
||||
WatchpointManager::~WatchpointManager()
|
||||
{
|
||||
fDebuggerInterface->ReleaseReference();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
WatchpointManager::Init()
|
||||
{
|
||||
return fLock.InitCheck();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
WatchpointManager::InstallWatchpoint(Watchpoint* watchpoint,
|
||||
bool enabled)
|
||||
{
|
||||
status_t error = B_OK;
|
||||
TRACE_CONTROL("WatchpointManager::InstallUserWatchpoint(%p, %d)\n",
|
||||
userWatchpoint, enabled);
|
||||
|
||||
AutoLocker<BLocker> installLocker(fLock);
|
||||
AutoLocker<Team> teamLocker(fTeam);
|
||||
|
||||
bool oldEnabled = watchpoint->IsEnabled();
|
||||
if (enabled == oldEnabled) {
|
||||
TRACE_CONTROL(" watchpoint already valid and with same enabled "
|
||||
"state\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
watchpoint->SetEnabled(enabled);
|
||||
|
||||
if (watchpoint->ShouldBeInstalled()) {
|
||||
error = fDebuggerInterface->InstallWatchpoint(watchpoint->Address(),
|
||||
watchpoint->Type(), watchpoint->Length());
|
||||
|
||||
if (error == B_OK)
|
||||
watchpoint->SetInstalled(true);
|
||||
} else {
|
||||
error = fDebuggerInterface->UninstallWatchpoint(watchpoint->Address());
|
||||
|
||||
if (error == B_OK)
|
||||
watchpoint->SetInstalled(false);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WatchpointManager::UninstallWatchpoint(Watchpoint* watchpoint)
|
||||
{
|
||||
AutoLocker<BLocker> installLocker(fLock);
|
||||
AutoLocker<Team> teamLocker(fTeam);
|
||||
|
||||
if (!watchpoint->IsInstalled())
|
||||
return;
|
||||
|
||||
status_t error = fDebuggerInterface->UninstallWatchpoint(
|
||||
watchpoint->Address());
|
||||
|
||||
if (error == B_OK)
|
||||
watchpoint->SetInstalled(false);
|
||||
}
|
37
src/apps/debugger/WatchpointManager.h
Normal file
37
src/apps/debugger/WatchpointManager.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2012, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WATCHPOINT_MANAGER_H
|
||||
#define WATCHPOINT_MANAGER_H
|
||||
|
||||
#include <Locker.h>
|
||||
|
||||
#include "Watchpoint.h"
|
||||
|
||||
|
||||
class DebuggerInterface;
|
||||
class Team;
|
||||
|
||||
|
||||
class WatchpointManager {
|
||||
public:
|
||||
WatchpointManager(Team* team,
|
||||
DebuggerInterface* debuggerInterface);
|
||||
~WatchpointManager();
|
||||
|
||||
status_t Init();
|
||||
|
||||
status_t InstallWatchpoint(Watchpoint* watchpoint,
|
||||
bool enabled);
|
||||
void UninstallWatchpoint(Watchpoint* watchpoint);
|
||||
|
||||
private:
|
||||
BLocker fLock; // used to synchronize un-/installing
|
||||
Team* fTeam;
|
||||
DebuggerInterface* fDebuggerInterface;
|
||||
};
|
||||
|
||||
|
||||
#endif // WATCHPOINT_MANAGER_H
|
@ -22,6 +22,7 @@
|
||||
#include "Statement.h"
|
||||
#include "TeamDebugInfo.h"
|
||||
#include "Tracing.h"
|
||||
#include "Watchpoint.h"
|
||||
|
||||
|
||||
// #pragma mark - BreakpointByAddressPredicate
|
||||
@ -45,6 +46,26 @@ private:
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - WatchpointByAddressPredicate
|
||||
|
||||
|
||||
struct Team::WatchpointByAddressPredicate
|
||||
: UnaryPredicate<Watchpoint> {
|
||||
WatchpointByAddressPredicate(target_addr_t address)
|
||||
:
|
||||
fAddress(address)
|
||||
{
|
||||
}
|
||||
|
||||
virtual int operator()(const Watchpoint* watchpoint) const
|
||||
{
|
||||
return -Watchpoint::CompareAddressWatchpoint(&fAddress, watchpoint);
|
||||
}
|
||||
|
||||
private:
|
||||
target_addr_t fAddress;
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - Team
|
||||
|
||||
@ -363,6 +384,67 @@ Team::RemoveUserBreakpoint(UserBreakpoint* userBreakpoint)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Team::AddWatchpoint(Watchpoint* watchpoint)
|
||||
{
|
||||
if (fWatchpoints.BinaryInsert(watchpoint, &Watchpoint::CompareWatchpoints))
|
||||
return true;
|
||||
|
||||
watchpoint->ReleaseReference();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::RemoveWatchpoint(Watchpoint* watchpoint)
|
||||
{
|
||||
int32 index = fWatchpoints.BinarySearchIndex(*watchpoint,
|
||||
&Watchpoint::CompareWatchpoints);
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
fWatchpoints.RemoveItemAt(index);
|
||||
watchpoint->ReleaseReference();
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Team::CountWatchpoints() const
|
||||
{
|
||||
return fWatchpoints.CountItems();
|
||||
}
|
||||
|
||||
|
||||
Watchpoint*
|
||||
Team::WatchpointAt(int32 index) const
|
||||
{
|
||||
return fWatchpoints.ItemAt(index);
|
||||
}
|
||||
|
||||
|
||||
Watchpoint*
|
||||
Team::WatchpointAtAddress(target_addr_t address) const
|
||||
{
|
||||
return fWatchpoints.BinarySearchByKey(address,
|
||||
&Watchpoint::CompareAddressWatchpoint);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::GetWatchpointsInAddressRange(TargetAddressRange range,
|
||||
BObjectList<Watchpoint>& watchpoints) const
|
||||
{
|
||||
int32 index = fWatchpoints.FindBinaryInsertionIndex(
|
||||
WatchpointByAddressPredicate(range.Start()));
|
||||
for (; Watchpoint* watchpoint = fWatchpoints.ItemAt(index); index++) {
|
||||
if (watchpoint->Address() > range.End())
|
||||
break;
|
||||
|
||||
watchpoints.AddItem(watchpoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Team::GetStatementAtAddress(target_addr_t address, FunctionInstance*& _function,
|
||||
Statement*& _statement)
|
||||
@ -539,6 +621,17 @@ Team::NotifyUserBreakpointChanged(UserBreakpoint* breakpoint)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::NotifyWatchpointChanged(Watchpoint* watchpoint)
|
||||
{
|
||||
for (ListenerList::Iterator it = fListeners.GetIterator();
|
||||
Listener* listener = it.Next();) {
|
||||
listener->WatchpointChanged(WatchpointEvent(
|
||||
TEAM_EVENT_WATCHPOINT_CHANGED, this, watchpoint));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::_NotifyThreadAdded(Thread* thread)
|
||||
{
|
||||
@ -579,28 +672,6 @@ 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
|
||||
|
||||
|
||||
@ -646,6 +717,18 @@ Team::BreakpointEvent::BreakpointEvent(uint32 type, Team* team,
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - WatchpointEvent
|
||||
|
||||
|
||||
Team::WatchpointEvent::WatchpointEvent(uint32 type, Team* team,
|
||||
Watchpoint* watchpoint)
|
||||
:
|
||||
Event(type, team),
|
||||
fWatchpoint(watchpoint)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - UserBreakpointEvent
|
||||
|
||||
|
||||
@ -730,3 +813,21 @@ void
|
||||
Team::Listener::UserBreakpointChanged(const Team::UserBreakpointEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::Listener::WatchpointAdded(const Team::WatchpointEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::Listener::WatchpointRemoved(const Team::WatchpointEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::Listener::WatchpointChanged(const Team::WatchpointEvent& event)
|
||||
{
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "Thread.h"
|
||||
#include "ThreadInfo.h"
|
||||
#include "UserBreakpoint.h"
|
||||
#include "Watchpoint.h"
|
||||
|
||||
|
||||
// team event types
|
||||
@ -33,7 +34,11 @@ enum {
|
||||
|
||||
TEAM_EVENT_BREAKPOINT_ADDED,
|
||||
TEAM_EVENT_BREAKPOINT_REMOVED,
|
||||
TEAM_EVENT_USER_BREAKPOINT_CHANGED
|
||||
TEAM_EVENT_USER_BREAKPOINT_CHANGED,
|
||||
|
||||
TEAM_EVENT_WATCHPOINT_ADDED,
|
||||
TEAM_EVENT_WATCHPOINT_REMOVED,
|
||||
TEAM_EVENT_WATCHPOINT_CHANGED
|
||||
};
|
||||
|
||||
|
||||
@ -55,10 +60,11 @@ class UserBreakpoint;
|
||||
class Team {
|
||||
public:
|
||||
class Event;
|
||||
class ThreadEvent;
|
||||
class ImageEvent;
|
||||
class BreakpointEvent;
|
||||
class ImageEvent;
|
||||
class ThreadEvent;
|
||||
class UserBreakpointEvent;
|
||||
class WatchpointEvent;
|
||||
class Listener;
|
||||
|
||||
public:
|
||||
@ -127,6 +133,19 @@ public:
|
||||
const UserBreakpointList& UserBreakpoints() const
|
||||
{ return fUserBreakpoints; }
|
||||
|
||||
bool AddWatchpoint(Watchpoint* watchpoint);
|
||||
// takes over reference (also on error)
|
||||
void RemoveWatchpoint(Watchpoint* watchpoint);
|
||||
// releases its own reference
|
||||
int32 CountWatchpoints() const;
|
||||
Watchpoint* WatchpointAt(int32 index) const;
|
||||
Watchpoint* WatchpointAtAddress(
|
||||
target_addr_t address) const;
|
||||
void GetWatchpointsInAddressRange(
|
||||
TargetAddressRange range,
|
||||
BObjectList<Watchpoint>& watchpoints)
|
||||
const;
|
||||
|
||||
status_t GetStatementAtAddress(target_addr_t address,
|
||||
FunctionInstance*& _function,
|
||||
Statement*& _statement);
|
||||
@ -158,20 +177,23 @@ public:
|
||||
void NotifyUserBreakpointChanged(
|
||||
UserBreakpoint* breakpoint);
|
||||
|
||||
// watchpoint related service methods
|
||||
void NotifyWatchpointChanged(
|
||||
Watchpoint* watchpoint);
|
||||
|
||||
private:
|
||||
struct BreakpointByAddressPredicate;
|
||||
struct WatchpointByAddressPredicate;
|
||||
|
||||
typedef BObjectList<Breakpoint> BreakpointList;
|
||||
typedef DoublyLinkedList<Listener> ListenerList;
|
||||
typedef BObjectList<Watchpoint> WatchpointList;
|
||||
|
||||
private:
|
||||
void _NotifyThreadAdded(Thread* thread);
|
||||
void _NotifyThreadRemoved(Thread* thread);
|
||||
void _NotifyImageAdded(Image* image);
|
||||
void _NotifyImageRemoved(Image* image);
|
||||
void _NotifyBreakpointAdded(Breakpoint* breakpoint);
|
||||
void _NotifyBreakpointRemoved(
|
||||
Breakpoint* breakpoint);
|
||||
|
||||
private:
|
||||
BLocker fLock;
|
||||
@ -185,6 +207,7 @@ private:
|
||||
ThreadList fThreads;
|
||||
ImageList fImages;
|
||||
BreakpointList fBreakpoints;
|
||||
WatchpointList fWatchpoints;
|
||||
UserBreakpointList fUserBreakpoints;
|
||||
ListenerList fListeners;
|
||||
};
|
||||
@ -237,6 +260,18 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
class Team::WatchpointEvent : public Event {
|
||||
public:
|
||||
WatchpointEvent(uint32 type, Team* team,
|
||||
Watchpoint* watchpoint);
|
||||
|
||||
Watchpoint* GetWatchpoint() const { return fWatchpoint; }
|
||||
|
||||
protected:
|
||||
Watchpoint* fWatchpoint;
|
||||
};
|
||||
|
||||
|
||||
class Team::UserBreakpointEvent : public Event {
|
||||
public:
|
||||
UserBreakpointEvent(uint32 type, Team* team,
|
||||
@ -275,6 +310,13 @@ public:
|
||||
const Team::BreakpointEvent& event);
|
||||
virtual void UserBreakpointChanged(
|
||||
const Team::UserBreakpointEvent& event);
|
||||
|
||||
virtual void WatchpointAdded(
|
||||
const Team::WatchpointEvent& event);
|
||||
virtual void WatchpointRemoved(
|
||||
const Team::WatchpointEvent& event);
|
||||
virtual void WatchpointChanged(
|
||||
const Team::WatchpointEvent& event);
|
||||
};
|
||||
|
||||
|
||||
|
65
src/apps/debugger/model/Watchpoint.cpp
Normal file
65
src/apps/debugger/model/Watchpoint.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2012, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "Watchpoint.h"
|
||||
|
||||
|
||||
Watchpoint::Watchpoint(target_addr_t address, uint32 type, int32 length)
|
||||
:
|
||||
fAddress(address),
|
||||
fType(type),
|
||||
fLength(length),
|
||||
fInstalled(false),
|
||||
fEnabled(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Watchpoint::~Watchpoint()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Watchpoint::SetInstalled(bool installed)
|
||||
{
|
||||
fInstalled = installed;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Watchpoint::SetEnabled(bool enabled)
|
||||
{
|
||||
fEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Watchpoint::Contains(target_addr_t address) const
|
||||
{
|
||||
return address >= fAddress && address <= (fAddress + fLength);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Watchpoint::CompareWatchpoints(const Watchpoint* a, const Watchpoint* b)
|
||||
{
|
||||
if (a->Address() < b->Address())
|
||||
return -1;
|
||||
return a->Address() == b->Address() ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Watchpoint::CompareAddressWatchpoint(const target_addr_t* address,
|
||||
const Watchpoint* watchpoint)
|
||||
{
|
||||
if (*address < watchpoint->Address())
|
||||
return -1;
|
||||
return *address == watchpoint->Address() ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
|
52
src/apps/debugger/model/Watchpoint.h
Normal file
52
src/apps/debugger/model/Watchpoint.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2012, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WATCHPOINT_H
|
||||
#define WATCHPOINT_H
|
||||
|
||||
|
||||
#include <Referenceable.h>
|
||||
|
||||
#include "types/Types.h"
|
||||
|
||||
|
||||
class Watchpoint : public BReferenceable {
|
||||
public:
|
||||
Watchpoint(target_addr_t address, uint32 type,
|
||||
int32 length);
|
||||
~Watchpoint();
|
||||
|
||||
target_addr_t Address() const { return fAddress; }
|
||||
uint32 Type() const { return fType; }
|
||||
int32 Length() const { return fLength; }
|
||||
|
||||
bool IsInstalled() const { return fInstalled; }
|
||||
void SetInstalled(bool installed);
|
||||
|
||||
bool IsEnabled() const { return fEnabled; }
|
||||
void SetEnabled(bool enabled);
|
||||
// WatchpointManager only
|
||||
|
||||
bool ShouldBeInstalled() const
|
||||
{ return fEnabled && !fInstalled; }
|
||||
|
||||
bool Contains(target_addr_t address) const;
|
||||
|
||||
static int CompareWatchpoints(const Watchpoint* a,
|
||||
const Watchpoint* b);
|
||||
static int CompareAddressWatchpoint(
|
||||
const target_addr_t* address,
|
||||
const Watchpoint* watchpoint);
|
||||
|
||||
private:
|
||||
target_addr_t fAddress;
|
||||
uint32 fType;
|
||||
int32 fLength;
|
||||
|
||||
bool fInstalled;
|
||||
bool fEnabled;
|
||||
};
|
||||
|
||||
|
||||
#endif // WATCHPOINT_H
|
@ -18,6 +18,7 @@
|
||||
#include "TeamUiSettings.h"
|
||||
#include "TeamUiSettingsFactory.h"
|
||||
#include "UserBreakpoint.h"
|
||||
#include "WatchpointSetting.h"
|
||||
|
||||
|
||||
TeamSettings::TeamSettings()
|
||||
@ -70,6 +71,23 @@ TeamSettings::SetTo(Team* team)
|
||||
}
|
||||
}
|
||||
|
||||
// add watchpoints
|
||||
for (int32 i = 0; Watchpoint* watchpoint = team->WatchpointAt(i); i++) {
|
||||
WatchpointSetting* watchpointSetting
|
||||
= new(std::nothrow) WatchpointSetting;
|
||||
if (watchpointSetting == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t error = watchpointSetting->SetTo(*watchpoint,
|
||||
watchpoint->IsEnabled());
|
||||
if (error == B_OK && !fWatchpoints.AddItem(watchpointSetting))
|
||||
error = B_NO_MEMORY;
|
||||
if (error != B_OK) {
|
||||
delete watchpointSetting;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -166,6 +184,20 @@ TeamSettings::BreakpointAt(int32 index) const
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
TeamSettings::CountWatchpoints() const
|
||||
{
|
||||
return fWatchpoints.CountItems();
|
||||
}
|
||||
|
||||
|
||||
const WatchpointSetting*
|
||||
TeamSettings::WatchpointAt(int32 index) const
|
||||
{
|
||||
return fWatchpoints.ItemAt(index);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
TeamSettings::CountUiSettings() const
|
||||
{
|
||||
|
@ -15,6 +15,7 @@ class BMessage;
|
||||
class Team;
|
||||
class BreakpointSetting;
|
||||
class TeamUiSettings;
|
||||
class WatchpointSetting;
|
||||
|
||||
|
||||
class TeamSettings {
|
||||
@ -33,6 +34,9 @@ public:
|
||||
int32 CountBreakpoints() const;
|
||||
const BreakpointSetting* BreakpointAt(int32 index) const;
|
||||
|
||||
int32 CountWatchpoints() const;
|
||||
const WatchpointSetting* WatchpointAt(int32 index) const;
|
||||
|
||||
int32 CountUiSettings() const;
|
||||
const TeamUiSettings* UiSettingAt(int32 index) const;
|
||||
const TeamUiSettings* UiSettingFor(const char* id) const;
|
||||
@ -44,12 +48,14 @@ public:
|
||||
private:
|
||||
typedef BObjectList<BreakpointSetting> BreakpointList;
|
||||
typedef BObjectList<TeamUiSettings> UiSettingsList;
|
||||
typedef BObjectList<WatchpointSetting> WatchpointList;
|
||||
|
||||
private:
|
||||
void _Unset();
|
||||
|
||||
private:
|
||||
BreakpointList fBreakpoints;
|
||||
WatchpointList fWatchpoints;
|
||||
UiSettingsList fUiSettings;
|
||||
BString fTeamName;
|
||||
};
|
||||
|
100
src/apps/debugger/settings/WatchpointSetting.cpp
Normal file
100
src/apps/debugger/settings/WatchpointSetting.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2012, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "WatchpointSetting.h"
|
||||
|
||||
#include <Message.h>
|
||||
|
||||
#include "Watchpoint.h"
|
||||
|
||||
|
||||
WatchpointSetting::WatchpointSetting()
|
||||
:
|
||||
fAddress(0),
|
||||
fType(0),
|
||||
fLength(0),
|
||||
fEnabled(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
WatchpointSetting::WatchpointSetting(const WatchpointSetting& other)
|
||||
:
|
||||
fAddress(other.fAddress),
|
||||
fType(other.fType),
|
||||
fLength(other.fLength),
|
||||
fEnabled(other.fEnabled)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
WatchpointSetting::~WatchpointSetting()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
WatchpointSetting::SetTo(const Watchpoint& watchpoint, bool enabled)
|
||||
{
|
||||
fAddress = watchpoint.Address();
|
||||
fType = watchpoint.Type();
|
||||
fLength = watchpoint.Length();
|
||||
fEnabled = enabled;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
WatchpointSetting::SetTo(const BMessage& archive)
|
||||
{
|
||||
if (archive.FindUInt64("address", &fAddress) != B_OK)
|
||||
fAddress = 0;
|
||||
|
||||
if (archive.FindUInt32("type", &fType) != B_OK)
|
||||
fType = 0;
|
||||
|
||||
if (archive.FindInt32("length", &fLength) != B_OK)
|
||||
fLength = 0;
|
||||
|
||||
if (archive.FindBool("enabled", &fEnabled) != B_OK)
|
||||
fEnabled = false;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
WatchpointSetting::WriteTo(BMessage& archive) const
|
||||
{
|
||||
archive.MakeEmpty();
|
||||
|
||||
status_t error;
|
||||
if ((error = archive.AddUInt64("address", fAddress)) != B_OK
|
||||
|| (error = archive.AddUInt32("type", fType)) != B_OK
|
||||
|| (error = archive.AddInt32("length", fLength)) != B_OK
|
||||
|| (error = archive.AddBool("enabled", fEnabled)) != B_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
WatchpointSetting&
|
||||
WatchpointSetting::operator=(const WatchpointSetting& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
fAddress = other.fAddress;
|
||||
fType = other.fType;
|
||||
fLength = other.fLength;
|
||||
fEnabled = other.fEnabled;
|
||||
|
||||
return *this;
|
||||
}
|
46
src/apps/debugger/settings/WatchpointSetting.h
Normal file
46
src/apps/debugger/settings/WatchpointSetting.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2012, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WATCHPOINT_SETTING_H
|
||||
#define WATCHPOINT_SETTING_H
|
||||
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#include "types/Types.h"
|
||||
|
||||
class BMessage;
|
||||
class Watchpoint;
|
||||
|
||||
|
||||
class WatchpointSetting {
|
||||
public:
|
||||
WatchpointSetting();
|
||||
WatchpointSetting(
|
||||
const WatchpointSetting& other);
|
||||
~WatchpointSetting();
|
||||
|
||||
status_t SetTo(const Watchpoint& watchpoint,
|
||||
bool enabled);
|
||||
status_t SetTo(const BMessage& archive);
|
||||
status_t WriteTo(BMessage& archive) const;
|
||||
|
||||
target_addr_t Address() const { return fAddress; }
|
||||
uint32 Type() const { return fType; }
|
||||
int32 Length() const { return fLength; }
|
||||
|
||||
bool IsEnabled() const { return fEnabled; }
|
||||
|
||||
WatchpointSetting& operator=(const WatchpointSetting& other);
|
||||
|
||||
private:
|
||||
target_addr_t fAddress;
|
||||
uint32 fType;
|
||||
int32 fLength;
|
||||
bool fEnabled;
|
||||
};
|
||||
|
||||
|
||||
#endif // BREAKPOINT_SETTING_H
|
@ -27,6 +27,7 @@ class UserInterfaceListener;
|
||||
class ValueNode;
|
||||
class ValueNodeContainer;
|
||||
class Variable;
|
||||
class Watchpoint;
|
||||
|
||||
|
||||
enum user_notification_type {
|
||||
@ -100,6 +101,17 @@ public:
|
||||
UserBreakpoint* breakpoint) = 0;
|
||||
// TODO: Consolidate those!
|
||||
|
||||
virtual void SetWatchpointRequested(target_addr_t address,
|
||||
uint32 type, int32 length,
|
||||
bool enabled) = 0;
|
||||
virtual void SetWatchpointEnabledRequested(
|
||||
Watchpoint* watchpoint,
|
||||
bool enabled) = 0;
|
||||
virtual void ClearWatchpointRequested(
|
||||
target_addr_t address) = 0;
|
||||
virtual void ClearWatchpointRequested(
|
||||
Watchpoint* watchpoint) = 0;
|
||||
|
||||
virtual void InspectRequested(
|
||||
target_addr_t address,
|
||||
TeamMemoryBlock::Listener* listener) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user