Implement debugger infrastructure for stop on...
...image load with name matching. - Move the stop on image load setting to Team, along with a new setting governing the use of the (also newly added) name list. - Add accessors for maintaining the name list, and events/notifications for listeners with regards to changes to all stop on image load settings. - Adjust user interface listener hooks for additional functionality.
This commit is contained in:
@@ -23,12 +23,17 @@ enum {
|
||||
MSG_ENABLE_WATCHPOINT = 'ewpt',
|
||||
MSG_DISABLE_WATCHPOINT = 'dwpt',
|
||||
MSG_STOP_ON_IMAGE_LOAD = 'tsil',
|
||||
MSG_ADD_STOP_IMAGE_NAME = 'asin',
|
||||
MSG_REMOVE_STOP_IMAGE_NAME = 'rsin',
|
||||
|
||||
MSG_THREAD_STATE_CHANGED = 'tsch',
|
||||
MSG_THREAD_CPU_STATE_CHANGED = 'tcsc',
|
||||
MSG_THREAD_STACK_TRACE_CHANGED = 'tstc',
|
||||
MSG_STACK_FRAME_VALUE_RETRIEVED = 'sfvr',
|
||||
MSG_IMAGE_DEBUG_INFO_CHANGED = 'idic',
|
||||
MSG_STOP_IMAGE_SETTINGS_CHANGED = 'sisc',
|
||||
MSG_STOP_IMAGE_NAME_ADDED = 'sina',
|
||||
MSG_STOP_IMAGE_NAME_REMOVED = 'sinr',
|
||||
MSG_CONSOLE_OUTPUT_RECEIVED = 'core',
|
||||
MSG_IMAGE_FILE_CHANGED = 'ifch',
|
||||
MSG_FUNCTION_SOURCE_CODE_CHANGED = 'fnsc',
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <Entry.h>
|
||||
#include <Message.h>
|
||||
#include <StringList.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
#include <AutoLocker.h>
|
||||
@@ -223,8 +224,7 @@ TeamDebugger::TeamDebugger(Listener* listener, UserInterface* userInterface,
|
||||
fTerminating(false),
|
||||
fKillTeamOnQuit(false),
|
||||
fCommandLineArgc(0),
|
||||
fCommandLineArgv(NULL),
|
||||
fStopOnImageLoad(false)
|
||||
fCommandLineArgv(NULL)
|
||||
{
|
||||
fUserInterface->AcquireReference();
|
||||
}
|
||||
@@ -608,13 +608,39 @@ TeamDebugger::MessageReceived(BMessage* message)
|
||||
case MSG_STOP_ON_IMAGE_LOAD:
|
||||
{
|
||||
bool enabled;
|
||||
bool useNames;
|
||||
if (message->FindBool("enabled", &enabled) != B_OK)
|
||||
break;
|
||||
|
||||
fStopOnImageLoad = enabled;
|
||||
if (message->FindBool("useNames", &useNames) != B_OK)
|
||||
break;
|
||||
|
||||
AutoLocker< ::Team> teamLocker(fTeam);
|
||||
fTeam->SetStopOnImageLoad(enabled, useNames);
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_ADD_STOP_IMAGE_NAME:
|
||||
{
|
||||
BString imageName;
|
||||
if (message->FindString("name", &imageName) != B_OK)
|
||||
break;
|
||||
|
||||
AutoLocker< ::Team> teamLocker(fTeam);
|
||||
fTeam->AddStopImageName(imageName);
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_REMOVE_STOP_IMAGE_NAME:
|
||||
{
|
||||
BString imageName;
|
||||
if (message->FindString("name", &imageName) != B_OK)
|
||||
break;
|
||||
|
||||
AutoLocker< ::Team> teamLocker(fTeam);
|
||||
fTeam->RemoveStopImageName(imageName);
|
||||
}
|
||||
|
||||
case MSG_SET_WATCHPOINT:
|
||||
case MSG_CLEAR_WATCHPOINT:
|
||||
{
|
||||
@@ -899,10 +925,29 @@ TeamDebugger::ClearBreakpointRequested(target_addr_t address)
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::SetStopOnImageLoadRequested(bool enabled)
|
||||
TeamDebugger::SetStopOnImageLoadRequested(bool enabled, bool useImageNames)
|
||||
{
|
||||
BMessage message(MSG_STOP_ON_IMAGE_LOAD);
|
||||
message.AddBool("enabled", enabled);
|
||||
message.AddBool("useNames", useImageNames);
|
||||
PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::AddStopImageNameRequested(const char* name)
|
||||
{
|
||||
BMessage message(MSG_ADD_STOP_IMAGE_NAME);
|
||||
message.AddString("name", name);
|
||||
PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamDebugger::RemoveStopImageNameRequested(const char* name)
|
||||
{
|
||||
BMessage message(MSG_REMOVE_STOP_IMAGE_NAME);
|
||||
message.AddString("name", name);
|
||||
PostMessage(&message);
|
||||
}
|
||||
|
||||
@@ -1525,13 +1570,30 @@ TeamDebugger::_HandleImageDebugInfoChanged(image_id imageID)
|
||||
if (thread != NULL) {
|
||||
fImageInfoPendingThreads->Remove(thread);
|
||||
ObjectDeleter<ImageInfoPendingThread> threadDeleter(thread);
|
||||
if (fStopOnImageLoad) {
|
||||
locker.Lock();
|
||||
if (fTeam->StopOnImageLoad()) {
|
||||
ThreadHandler* handler = _GetThreadHandler(thread->ThreadID());
|
||||
BReference<ThreadHandler> handlerReference(handler);
|
||||
|
||||
if (handler != NULL && handler->HandleThreadDebugged(NULL))
|
||||
bool stop = true;
|
||||
if (fTeam->StopImageNameListEnabled()) {
|
||||
const BStringList& nameList = fTeam->StopImageNames();
|
||||
const BString& imageName = image->Name();
|
||||
// only match on the image filename itself
|
||||
const char* rawImageName = imageName.String()
|
||||
+ imageName.FindLast('/') + 1;
|
||||
stop = nameList.HasString(rawImageName);
|
||||
}
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
if (stop && handler != NULL
|
||||
&& handler->HandleThreadDebugged(NULL)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else
|
||||
locker.Unlock();
|
||||
|
||||
fDebuggerInterface->ContinueThread(thread->ThreadID());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ private:
|
||||
ValueNode* valueNode);
|
||||
virtual void ThreadActionRequested(thread_id threadID,
|
||||
uint32 action, target_addr_t address);
|
||||
|
||||
virtual void SetBreakpointRequested(target_addr_t address,
|
||||
bool enabled, bool hidden = false);
|
||||
virtual void SetBreakpointEnabledRequested(
|
||||
@@ -78,7 +79,14 @@ private:
|
||||
virtual void ClearBreakpointRequested(target_addr_t address);
|
||||
virtual void ClearBreakpointRequested(
|
||||
UserBreakpoint* breakpoint);
|
||||
virtual void SetStopOnImageLoadRequested(bool enabled);
|
||||
|
||||
virtual void SetStopOnImageLoadRequested(bool enabled,
|
||||
bool useImageNames);
|
||||
virtual void AddStopImageNameRequested(
|
||||
const char* name);
|
||||
virtual void RemoveStopImageNameRequested(
|
||||
const char* name);
|
||||
|
||||
virtual void SetWatchpointRequested(target_addr_t address,
|
||||
uint32 type, int32 length, bool enabled);
|
||||
virtual void SetWatchpointEnabledRequested(
|
||||
@@ -207,7 +215,6 @@ private:
|
||||
TeamSettings fTeamSettings;
|
||||
int fCommandLineArgc;
|
||||
const char** fCommandLineArgv;
|
||||
bool fStopOnImageLoad;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include "Team.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <AutoLocker.h>
|
||||
@@ -79,7 +77,9 @@ Team::Team(team_id teamID, TeamMemory* teamMemory, Architecture* architecture,
|
||||
fTeamMemory(teamMemory),
|
||||
fTypeInformation(typeInformation),
|
||||
fArchitecture(architecture),
|
||||
fDebugInfo(debugInfo)
|
||||
fDebugInfo(debugInfo),
|
||||
fStopOnImageLoad(false),
|
||||
fStopImageNameListEnabled(false)
|
||||
{
|
||||
fDebugInfo->AcquireReference();
|
||||
}
|
||||
@@ -274,6 +274,43 @@ Team::Images() const
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Team::AddStopImageName(const BString& name)
|
||||
{
|
||||
if (!fStopImageNames.Add(name))
|
||||
return false;
|
||||
|
||||
fStopImageNames.Sort();
|
||||
|
||||
NotifyStopImageNameAdded(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::RemoveStopImageName(const BString& name)
|
||||
{
|
||||
fStopImageNames.Remove(name);
|
||||
NotifyStopImageNameRemoved(name);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::SetStopOnImageLoad(bool enabled, bool useImageNameList)
|
||||
{
|
||||
fStopOnImageLoad = enabled;
|
||||
fStopImageNameListEnabled = useImageNameList;
|
||||
NotifyStopOnImageLoadChanged(enabled, useImageNameList);
|
||||
}
|
||||
|
||||
|
||||
const BStringList&
|
||||
Team::StopImageNames() const
|
||||
{
|
||||
return fStopImageNames;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Team::AddBreakpoint(Breakpoint* breakpoint)
|
||||
{
|
||||
@@ -614,6 +651,41 @@ Team::NotifyImageDebugInfoChanged(Image* image)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::NotifyStopOnImageLoadChanged(bool enabled, bool useImageNameList)
|
||||
{
|
||||
for (ListenerList::Iterator it = fListeners.GetIterator();
|
||||
Listener* listener = it.Next();) {
|
||||
listener->StopOnImageLoadSettingsChanged(
|
||||
ImageLoadEvent(TEAM_EVENT_IMAGE_LOAD_SETTINGS_CHANGED, this,
|
||||
enabled, useImageNameList));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::NotifyStopImageNameAdded(const BString& name)
|
||||
{
|
||||
for (ListenerList::Iterator it = fListeners.GetIterator();
|
||||
Listener* listener = it.Next();) {
|
||||
listener->StopOnImageLoadNameAdded(
|
||||
ImageLoadNameEvent(TEAM_EVENT_IMAGE_LOAD_NAME_ADDED, this, name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::NotifyStopImageNameRemoved(const BString& name)
|
||||
{
|
||||
for (ListenerList::Iterator it = fListeners.GetIterator();
|
||||
Listener* listener = it.Next();) {
|
||||
listener->StopOnImageLoadNameRemoved(
|
||||
ImageLoadNameEvent(TEAM_EVENT_IMAGE_LOAD_NAME_REMOVED, this,
|
||||
name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::NotifyConsoleOutputReceived(int32 fd, const BString& output)
|
||||
{
|
||||
@@ -732,6 +804,31 @@ Team::ImageEvent::ImageEvent(uint32 type, Image* image)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - ImageLoadEvent
|
||||
|
||||
|
||||
Team::ImageLoadEvent::ImageLoadEvent(uint32 type, Team* team,
|
||||
bool stopOnImageLoad, bool stopImageNameListEnabled)
|
||||
:
|
||||
Event(type, team),
|
||||
fStopOnImageLoad(stopOnImageLoad),
|
||||
fStopImageNameListEnabled(stopImageNameListEnabled)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - ImageLoadNameEvent
|
||||
|
||||
|
||||
Team::ImageLoadNameEvent::ImageLoadNameEvent(uint32 type, Team* team,
|
||||
const BString& name)
|
||||
:
|
||||
Event(type, team),
|
||||
fImageName(name)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - BreakpointEvent
|
||||
|
||||
|
||||
@@ -849,6 +946,26 @@ Team::Listener::ImageDebugInfoChanged(const Team::ImageEvent& event)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::Listener::StopOnImageLoadSettingsChanged(
|
||||
const Team::ImageLoadEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::Listener::StopOnImageLoadNameAdded(const Team::ImageLoadNameEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::Listener::StopOnImageLoadNameRemoved(
|
||||
const Team::ImageLoadNameEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Team::Listener::ConsoleOutputReceived(const Team::ConsoleOutputEvent& event)
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include <Locker.h>
|
||||
#include <StringList.h>
|
||||
|
||||
#include <ObjectList.h>
|
||||
|
||||
@@ -33,6 +34,10 @@ enum {
|
||||
|
||||
TEAM_EVENT_IMAGE_DEBUG_INFO_CHANGED,
|
||||
|
||||
TEAM_EVENT_IMAGE_LOAD_SETTINGS_CHANGED,
|
||||
TEAM_EVENT_IMAGE_LOAD_NAME_ADDED,
|
||||
TEAM_EVENT_IMAGE_LOAD_NAME_REMOVED,
|
||||
|
||||
TEAM_EVENT_CONSOLE_OUTPUT_RECEIVED,
|
||||
|
||||
TEAM_EVENT_BREAKPOINT_ADDED,
|
||||
@@ -50,6 +55,7 @@ enum {
|
||||
|
||||
class Architecture;
|
||||
class Breakpoint;
|
||||
class BStringList;
|
||||
class Function;
|
||||
class FunctionID;
|
||||
class FunctionInstance;
|
||||
@@ -70,6 +76,8 @@ public:
|
||||
class ConsoleOutputEvent;
|
||||
class DebugReportEvent;
|
||||
class ImageEvent;
|
||||
class ImageLoadEvent;
|
||||
class ImageLoadNameEvent;
|
||||
class ThreadEvent;
|
||||
class UserBreakpointEvent;
|
||||
class WatchpointEvent;
|
||||
@@ -117,6 +125,17 @@ public:
|
||||
Image* ImageByAddress(target_addr_t address) const;
|
||||
const ImageList& Images() const;
|
||||
|
||||
bool AddStopImageName(const BString& name);
|
||||
void RemoveStopImageName(const BString& name);
|
||||
const BStringList& StopImageNames() const;
|
||||
|
||||
void SetStopOnImageLoad(bool enabled,
|
||||
bool useImageNameList);
|
||||
bool StopOnImageLoad() const
|
||||
{ return fStopOnImageLoad; }
|
||||
bool StopImageNameListEnabled() const
|
||||
{ return fStopImageNameListEnabled; }
|
||||
|
||||
bool AddBreakpoint(Breakpoint* breakpoint);
|
||||
// takes over reference (also on error)
|
||||
void RemoveBreakpoint(Breakpoint* breakpoint);
|
||||
@@ -183,6 +202,13 @@ public:
|
||||
// service methods for Image
|
||||
void NotifyImageDebugInfoChanged(Image* image);
|
||||
|
||||
// service methods for Image load settings
|
||||
void NotifyStopOnImageLoadChanged(bool enabled,
|
||||
bool useImageNameList);
|
||||
void NotifyStopImageNameAdded(const BString& name);
|
||||
void NotifyStopImageNameRemoved(
|
||||
const BString& name);
|
||||
|
||||
// service methods for console output
|
||||
void NotifyConsoleOutputReceived(
|
||||
int32 fd, const BString& output);
|
||||
@@ -223,6 +249,9 @@ private:
|
||||
BString fName;
|
||||
ThreadList fThreads;
|
||||
ImageList fImages;
|
||||
bool fStopOnImageLoad;
|
||||
bool fStopImageNameListEnabled;
|
||||
BStringList fStopImageNames;
|
||||
BreakpointList fBreakpoints;
|
||||
WatchpointList fWatchpoints;
|
||||
UserBreakpointList fUserBreakpoints;
|
||||
@@ -265,6 +294,35 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
class Team::ImageLoadEvent : public Event {
|
||||
public:
|
||||
ImageLoadEvent(uint32 type, Team* team,
|
||||
bool stopOnImageLoad,
|
||||
bool stopImageNameListEnabled);
|
||||
|
||||
bool StopOnImageLoad() const
|
||||
{ return fStopOnImageLoad; }
|
||||
bool StopImageNameListEnabled() const
|
||||
{ return fStopImageNameListEnabled; }
|
||||
|
||||
private:
|
||||
bool fStopOnImageLoad;
|
||||
bool fStopImageNameListEnabled;
|
||||
};
|
||||
|
||||
|
||||
class Team::ImageLoadNameEvent : public Event {
|
||||
public:
|
||||
ImageLoadNameEvent(uint32 type, Team* team,
|
||||
const BString& name);
|
||||
|
||||
const BString& ImageName() const { return fImageName; }
|
||||
|
||||
private:
|
||||
BString fImageName;
|
||||
};
|
||||
|
||||
|
||||
class Team::BreakpointEvent : public Event {
|
||||
public:
|
||||
BreakpointEvent(uint32 type, Team* team,
|
||||
@@ -346,6 +404,13 @@ public:
|
||||
virtual void ImageDebugInfoChanged(
|
||||
const Team::ImageEvent& event);
|
||||
|
||||
virtual void StopOnImageLoadSettingsChanged(
|
||||
const Team::ImageLoadEvent& event);
|
||||
virtual void StopOnImageLoadNameAdded(
|
||||
const Team::ImageLoadNameEvent& event);
|
||||
virtual void StopOnImageLoadNameRemoved(
|
||||
const Team::ImageLoadNameEvent& event);
|
||||
|
||||
virtual void ConsoleOutputReceived(
|
||||
const Team::ConsoleOutputEvent& event);
|
||||
|
||||
|
||||
@@ -106,7 +106,12 @@ public:
|
||||
UserBreakpoint* breakpoint) = 0;
|
||||
// TODO: Consolidate those!
|
||||
|
||||
virtual void SetStopOnImageLoadRequested(bool enabled) = 0;
|
||||
virtual void SetStopOnImageLoadRequested(bool enabled,
|
||||
bool useImageNames) = 0;
|
||||
virtual void AddStopImageNameRequested(
|
||||
const char* name) = 0;
|
||||
virtual void RemoveStopImageNameRequested(
|
||||
const char* name) = 0;
|
||||
|
||||
virtual void SetWatchpointRequested(target_addr_t address,
|
||||
uint32 type, int32 length,
|
||||
|
||||
Reference in New Issue
Block a user