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:
Rene Gollent
2013-07-07 00:39:04 -04:00
parent adc742c508
commit cae8421db8
6 changed files with 274 additions and 13 deletions
+5
View File
@@ -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',
+69 -7
View File
@@ -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());
}
}
+9 -2
View File
@@ -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;
};
+120 -3
View File
@@ -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)
{
+65
View File
@@ -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,