diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h index 288eea8346..e0efd00331 100644 --- a/src/apps/debugger/MessageCodes.h +++ b/src/apps/debugger/MessageCodes.h @@ -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', diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp index 449eb87484..4e7b62b9c9 100644 --- a/src/apps/debugger/controllers/TeamDebugger.cpp +++ b/src/apps/debugger/controllers/TeamDebugger.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -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 threadDeleter(thread); - if (fStopOnImageLoad) { + locker.Lock(); + if (fTeam->StopOnImageLoad()) { ThreadHandler* handler = _GetThreadHandler(thread->ThreadID()); BReference 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()); } } diff --git a/src/apps/debugger/controllers/TeamDebugger.h b/src/apps/debugger/controllers/TeamDebugger.h index b869ece4f7..c91fc583da 100644 --- a/src/apps/debugger/controllers/TeamDebugger.h +++ b/src/apps/debugger/controllers/TeamDebugger.h @@ -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; }; diff --git a/src/apps/debugger/model/Team.cpp b/src/apps/debugger/model/Team.cpp index 016da1c742..47ca84dc99 100644 --- a/src/apps/debugger/model/Team.cpp +++ b/src/apps/debugger/model/Team.cpp @@ -7,8 +7,6 @@ #include "Team.h" -#include - #include #include @@ -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) { diff --git a/src/apps/debugger/model/Team.h b/src/apps/debugger/model/Team.h index 98a2fb2c18..5428084796 100644 --- a/src/apps/debugger/model/Team.h +++ b/src/apps/debugger/model/Team.h @@ -8,6 +8,7 @@ #include +#include #include @@ -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); diff --git a/src/apps/debugger/user_interface/UserInterface.h b/src/apps/debugger/user_interface/UserInterface.h index 54731566f5..cb00459c6d 100644 --- a/src/apps/debugger/user_interface/UserInterface.h +++ b/src/apps/debugger/user_interface/UserInterface.h @@ -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,