diff --git a/src/apps/debugger/TeamDebugger.cpp b/src/apps/debugger/TeamDebugger.cpp index b07f958a32..0fdbe4df84 100644 --- a/src/apps/debugger/TeamDebugger.cpp +++ b/src/apps/debugger/TeamDebugger.cpp @@ -799,7 +799,7 @@ TeamDebugger::_DebugEventListener() void TeamDebugger::_HandleDebuggerMessage(DebugEvent* event) { - TRACE_EVENTS("TeamDebugger::_HandleDebuggerMessage(): %d\n", + TRACE_EVENTS("TeamDebugger::_HandleDebuggerMessage(): %ld\n", event->EventType()); bool handled = false; @@ -884,6 +884,25 @@ TeamDebugger::_HandleDebuggerMessage(DebugEvent* event) handled = _HandleThreadCreated(threadEvent); break; } + case DEBUGGER_MESSAGE_THREAD_RENAMED: + { + ThreadRenamedEvent* threadEvent + = dynamic_cast(event); + TRACE_EVENTS("DEBUGGER_MESSAGE_THREAD_RENAMED: thread: %ld " + "(\"%s\")\n", + threadEvent->RenamedThread(), threadEvent->NewName()); + handled = _HandleThreadRenamed(threadEvent); + break; + } + case DEBUGGER_MESSAGE_THREAD_PRIORITY_CHANGED: + { + ThreadPriorityChangedEvent* threadEvent + = dynamic_cast(event); + TRACE_EVENTS("B_DEBUGGER_MESSAGE_THREAD_PRIORITY_CHANGED: thread:" + " %ld\n", threadEvent->ChangedThread()); + handled = _HandleThreadPriorityChanged(threadEvent); + break; + } case B_DEBUGGER_MESSAGE_THREAD_DELETED: TRACE_EVENTS("B_DEBUGGER_MESSAGE_THREAD_DELETED: thread: %ld\n", event->Thread()); @@ -919,7 +938,7 @@ TeamDebugger::_HandleDebuggerMessage(DebugEvent* event) break; default: WARNING("TeamDebugger for team %ld: unknown event type: " - "%d\n", fTeamID, event->EventType()); + "%ld\n", fTeamID, event->EventType()); break; } @@ -953,6 +972,29 @@ TeamDebugger::_HandleThreadCreated(ThreadCreatedEvent* event) } +bool +TeamDebugger::_HandleThreadRenamed(ThreadRenamedEvent* event) +{ + AutoLocker< ::Team> locker(fTeam); + + ::Thread* thread = fTeam->ThreadByID(event->RenamedThread()); + + if (thread != NULL) + thread->SetName(event->NewName()); + + return false; +} + + +bool +TeamDebugger::_HandleThreadPriorityChanged(ThreadPriorityChangedEvent*) +{ + // TODO: implement once we actually track thread priorities + + return false; +} + + bool TeamDebugger::_HandleThreadDeleted(ThreadDeletedEvent* event) { diff --git a/src/apps/debugger/TeamDebugger.h b/src/apps/debugger/TeamDebugger.h index ac4181d7d8..ab616c6b7c 100644 --- a/src/apps/debugger/TeamDebugger.h +++ b/src/apps/debugger/TeamDebugger.h @@ -95,6 +95,10 @@ private: bool _HandleThreadCreated( ThreadCreatedEvent* event); + bool _HandleThreadRenamed( + ThreadRenamedEvent* event); + bool _HandleThreadPriorityChanged( + ThreadPriorityChangedEvent* event); bool _HandleThreadDeleted( ThreadDeletedEvent* event); bool _HandleImageCreated( diff --git a/src/apps/debugger/debugger_interface/DebugEvent.cpp b/src/apps/debugger/debugger_interface/DebugEvent.cpp index 0891249d44..45d29a9171 100644 --- a/src/apps/debugger/debugger_interface/DebugEvent.cpp +++ b/src/apps/debugger/debugger_interface/DebugEvent.cpp @@ -11,7 +11,7 @@ // #pragma mark - DebugEvent -DebugEvent::DebugEvent(debug_debugger_message eventType, team_id team, +DebugEvent::DebugEvent(int32 eventType, team_id team, thread_id thread) : fEventType(eventType), @@ -155,6 +155,32 @@ ThreadCreatedEvent::ThreadCreatedEvent(team_id team, thread_id thread, } +// #pragma mark - ThreadRenamedEvent + + +ThreadRenamedEvent::ThreadRenamedEvent(team_id team, thread_id thread, + thread_id renamedThread, const char* newName) + : + DebugEvent(DEBUGGER_MESSAGE_THREAD_RENAMED, team, thread), + fRenamedThread(renamedThread) +{ + strlcpy(fName, newName, sizeof(fName)); +} + + +// #pragma mark - ThreadPriorityChangedEvent + + +ThreadPriorityChangedEvent::ThreadPriorityChangedEvent(team_id team, + thread_id thread, thread_id changedThread, int32 newPriority) + : + DebugEvent(DEBUGGER_MESSAGE_THREAD_PRIORITY_CHANGED, team, thread), + fChangedThread(changedThread), + fNewPriority(newPriority) +{ +} + + // #pragma mark - ThreadDeletedEvent diff --git a/src/apps/debugger/debugger_interface/DebugEvent.h b/src/apps/debugger/debugger_interface/DebugEvent.h index f81a5e4ee9..dda16cb1dd 100644 --- a/src/apps/debugger/debugger_interface/DebugEvent.h +++ b/src/apps/debugger/debugger_interface/DebugEvent.h @@ -14,13 +14,21 @@ class CpuState; +// constants for synthetic events generated via the +// start_system_watching() interface +enum { + DEBUGGER_MESSAGE_THREAD_RENAMED = 'dmtr', + DEBUGGER_MESSAGE_THREAD_PRIORITY_CHANGED = 'dmpc' +}; + + class DebugEvent { public: - DebugEvent(debug_debugger_message eventType, + DebugEvent(int32 eventType, team_id team, thread_id thread); virtual ~DebugEvent(); - debug_debugger_message EventType() const { return fEventType; } + int32 EventType() const { return fEventType; } team_id Team() const { return fTeam; } thread_id Thread() const { return fThread; } @@ -28,7 +36,7 @@ public: void SetThreadStopped(bool stopped); private: - debug_debugger_message fEventType; + int32 fEventType; team_id fTeam; thread_id fThread; bool fThreadStopped; @@ -127,6 +135,36 @@ private: }; +class ThreadRenamedEvent : public DebugEvent { +public: + ThreadRenamedEvent(team_id team, + thread_id thread, thread_id renamedThread, + const char* name); + + thread_id RenamedThread() const { return fRenamedThread; } + const char* NewName() const { return fName; } + +private: + thread_id fRenamedThread; + char fName[B_OS_NAME_LENGTH]; +}; + + +class ThreadPriorityChangedEvent : public DebugEvent { +public: + ThreadPriorityChangedEvent(team_id team, + thread_id thread, thread_id changedThread, + int32 newPriority); + + thread_id ChangedThread() const { return fChangedThread; } + int32 NewPriority() const { return fNewPriority; } + +private: + thread_id fChangedThread; + int32 fNewPriority; +}; + + class ThreadDeletedEvent : public DebugEvent { public: ThreadDeletedEvent(team_id team, diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp index ddcd4f825b..4b077943e5 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp @@ -13,7 +13,10 @@ #include #include +#include +#include #include +#include #include "debug_utils.h" @@ -227,6 +230,7 @@ DebuggerInterface::DebuggerInterface(team_id teamID) fTeamID(teamID), fDebuggerPort(-1), fNubPort(-1), + fSystemWatchPort(-1), fDebugContextPool(NULL), fArchitecture(NULL) { @@ -272,6 +276,16 @@ DebuggerInterface::Init() if (fNubPort < 0) return fNubPort; + snprintf(buffer, sizeof(buffer), "team %ld debug system watcher", fTeamID); + fSystemWatchPort = create_port(100, buffer); + if (fSystemWatchPort < 0) + return fSystemWatchPort; + + error = start_system_watching(fTeamID, B_WATCH_SYSTEM_THREAD_PROPERTIES, + fSystemWatchPort, 0); + if (error != B_OK) + return error; + // create debug context pool fDebugContextPool = new(std::nothrow) DebugContextPool(fTeamID, fNubPort); if (fDebugContextPool == NULL) @@ -295,6 +309,9 @@ DebuggerInterface::Close(bool killTeam) if (fDebuggerPort >= 0) delete_port(fDebuggerPort); + + if (fSystemWatchPort >= 0) + delete_port(fSystemWatchPort); } @@ -304,11 +321,32 @@ DebuggerInterface::GetNextDebugEvent(DebugEvent*& _event) while (true) { debug_debugger_message_data message; int32 messageCode; - ssize_t size = read_port(fDebuggerPort, &messageCode, &message, + + object_wait_info infos[2]; + infos[0].object = fDebuggerPort; + infos[0].type = B_OBJECT_TYPE_PORT; + infos[0].events = B_EVENT_READ; + infos[1].object = fSystemWatchPort; + infos[1].type = B_OBJECT_TYPE_PORT; + infos[1].events = B_EVENT_READ; + + ssize_t size = wait_for_objects(infos, 2); + if (size < 0) { + if (size == B_INTERRUPTED) + continue; + + return size; + } + + if (infos[1].events & B_EVENT_READ) + return _GetNextSystemWatchEvent(_event); + + size = read_port(fDebuggerPort, &messageCode, &message, sizeof(message)); if (size < 0) { if (size == B_INTERRUPTED) continue; + return size; } @@ -719,3 +757,66 @@ DebuggerInterface::_CreateDebugEvent(int32 messageCode, return B_OK; } + + +status_t +DebuggerInterface::_GetNextSystemWatchEvent(DebugEvent*& _event) +{ + while (true) { + char buffer[1024]; + int32 messageCode; + ssize_t bytesRead = read_port(fSystemWatchPort, &messageCode, + buffer, sizeof(buffer)); + + if (bytesRead < 0) { + if (bytesRead == B_INTERRUPTED) + continue; + + return bytesRead; + } + + KMessage message; + status_t error = message.SetTo((const void *)buffer, bytesRead); + if (error != B_OK) + return error; + if (message.What() != B_SYSTEM_OBJECT_UPDATE) + return B_BAD_DATA; + + int32 opcode = 0; + if (message.FindInt32("opcode", &opcode) != B_OK) + return B_BAD_DATA; + + DebugEvent* event = NULL; + switch (opcode) + { + case B_THREAD_NAME_CHANGED: + { + int32 threadID = -1; + if (message.FindInt32("thread", &threadID) != B_OK) + break; + + thread_info info; + error = get_thread_info(threadID, &info); + if (error != B_OK) + break; + + event = new(std::nothrow) ThreadRenamedEvent(fTeamID, + threadID, threadID, info.name); + break; + } + + default: + { + error = B_BAD_DATA; + break; + } + } + + if (event != NULL) + _event = event; + + return error; + } + + return B_OK; +} diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.h b/src/apps/debugger/debugger_interface/DebuggerInterface.h index 165f76fe06..1d4e14680d 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.h +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.h @@ -73,10 +73,13 @@ private: const debug_debugger_message_data& message, bool& _ignore, DebugEvent*& _event); + status_t _GetNextSystemWatchEvent(DebugEvent*& _event); + private: team_id fTeamID; port_id fDebuggerPort; port_id fNubPort; + port_id fSystemWatchPort; DebugContextPool* fDebugContextPool; Architecture* fArchitecture; };