* Added notifications for thread state/CPU state/stack trace changes. The team
window listens for those and updates the buttons correctly. * Added basic handling for the thread stopping debug events in the team debugger. * Forward the thread run/stop/step requests to the team debugger and actually run/stop/step the thread. Running/stopping works, all three stepping actions just step by a single instruction ATM, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31107 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
18882afba2
commit
b6aff5aa83
|
@ -7,10 +7,15 @@
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MSG_THREAD_RUN = 'run_',
|
MSG_THREAD_RUN = 'run_',
|
||||||
MSG_THREAD_STEP_OVER = 'stov',
|
MSG_THREAD_STOP = 'stop',
|
||||||
MSG_THREAD_STEP_INTO = 'stin',
|
MSG_THREAD_STEP_OVER = 'stov',
|
||||||
MSG_THREAD_STEP_OUT = 'stou'
|
MSG_THREAD_STEP_INTO = 'stin',
|
||||||
|
MSG_THREAD_STEP_OUT = 'stou',
|
||||||
|
|
||||||
|
MSG_THREAD_STATE_CHANGED = 'tsch',
|
||||||
|
MSG_THREAD_CPU_STATE_CHANGED = 'tcsc',
|
||||||
|
MSG_THREAD_STACK_TRACE_CHANGED = 'tstc'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,39 @@ Team::RemoveListener(Listener* listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Team::NotifyThreadStateChanged(Thread* thread)
|
||||||
|
{
|
||||||
|
for (ListenerList::Iterator it = fListeners.GetIterator();
|
||||||
|
Listener* listener = it.Next();) {
|
||||||
|
listener->ThreadStateChanged(
|
||||||
|
ThreadEvent(TEAM_EVENT_THREAD_STATE_CHANGED, thread));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Team::NotifyThreadCpuStateChanged(Thread* thread)
|
||||||
|
{
|
||||||
|
for (ListenerList::Iterator it = fListeners.GetIterator();
|
||||||
|
Listener* listener = it.Next();) {
|
||||||
|
listener->ThreadCpuStateChanged(
|
||||||
|
ThreadEvent(TEAM_EVENT_THREAD_CPU_STATE_CHANGED, thread));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Team::NotifyThreadStackTraceChanged(Thread* thread)
|
||||||
|
{
|
||||||
|
for (ListenerList::Iterator it = fListeners.GetIterator();
|
||||||
|
Listener* listener = it.Next();) {
|
||||||
|
listener->ThreadStackTraceChanged(
|
||||||
|
ThreadEvent(TEAM_EVENT_THREAD_STACK_TRACE_CHANGED, thread));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Team::_NotifyThreadAdded(Thread* thread)
|
Team::_NotifyThreadAdded(Thread* thread)
|
||||||
{
|
{
|
||||||
|
@ -307,3 +340,21 @@ void
|
||||||
Team::Listener::ImageRemoved(const Team::ImageEvent& event)
|
Team::Listener::ImageRemoved(const Team::ImageEvent& event)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Team::Listener::ThreadStateChanged(const Team::ThreadEvent& event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Team::Listener::ThreadCpuStateChanged(const Team::ThreadEvent& event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Team::Listener::ThreadStackTraceChanged(const Team::ThreadEvent& event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -18,7 +18,11 @@ enum {
|
||||||
TEAM_EVENT_THREAD_ADDED,
|
TEAM_EVENT_THREAD_ADDED,
|
||||||
TEAM_EVENT_THREAD_REMOVED,
|
TEAM_EVENT_THREAD_REMOVED,
|
||||||
TEAM_EVENT_IMAGE_ADDED,
|
TEAM_EVENT_IMAGE_ADDED,
|
||||||
TEAM_EVENT_IMAGE_REMOVED
|
TEAM_EVENT_IMAGE_REMOVED,
|
||||||
|
|
||||||
|
TEAM_EVENT_THREAD_STATE_CHANGED,
|
||||||
|
TEAM_EVENT_THREAD_CPU_STATE_CHANGED,
|
||||||
|
TEAM_EVENT_THREAD_STACK_TRACE_CHANGED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,6 +63,11 @@ public:
|
||||||
void AddListener(Listener* listener);
|
void AddListener(Listener* listener);
|
||||||
void RemoveListener(Listener* listener);
|
void RemoveListener(Listener* listener);
|
||||||
|
|
||||||
|
// service methods for Thread
|
||||||
|
void NotifyThreadStateChanged(Thread* thread);
|
||||||
|
void NotifyThreadCpuStateChanged(Thread* thread);
|
||||||
|
void NotifyThreadStackTraceChanged(Thread* thread);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef DoublyLinkedList<Listener> ListenerList;
|
typedef DoublyLinkedList<Listener> ListenerList;
|
||||||
|
|
||||||
|
@ -121,6 +130,13 @@ public:
|
||||||
|
|
||||||
virtual void ImageAdded(const Team::ImageEvent& event);
|
virtual void ImageAdded(const Team::ImageEvent& event);
|
||||||
virtual void ImageRemoved(const Team::ImageEvent& event);
|
virtual void ImageRemoved(const Team::ImageEvent& event);
|
||||||
|
|
||||||
|
virtual void ThreadStateChanged(
|
||||||
|
const Team::ThreadEvent& event);
|
||||||
|
virtual void ThreadCpuStateChanged(
|
||||||
|
const Team::ThreadEvent& event);
|
||||||
|
virtual void ThreadStackTraceChanged(
|
||||||
|
const Team::ThreadEvent& event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "CpuState.h"
|
#include "CpuState.h"
|
||||||
#include "DebuggerInterface.h"
|
#include "DebuggerInterface.h"
|
||||||
|
#include "MessageCodes.h"
|
||||||
#include "Team.h"
|
#include "Team.h"
|
||||||
#include "TeamDebugModel.h"
|
#include "TeamDebugModel.h"
|
||||||
|
|
||||||
|
@ -168,6 +169,19 @@ void
|
||||||
TeamDebugger::MessageReceived(BMessage* message)
|
TeamDebugger::MessageReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
|
case MSG_THREAD_RUN:
|
||||||
|
case MSG_THREAD_STOP:
|
||||||
|
case MSG_THREAD_STEP_OVER:
|
||||||
|
case MSG_THREAD_STEP_INTO:
|
||||||
|
case MSG_THREAD_STEP_OUT:
|
||||||
|
{
|
||||||
|
int32 threadID;
|
||||||
|
if (message->FindInt32("thread", &threadID) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
_HandleThreadAction(threadID, message->what);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
BLooper::MessageReceived(message);
|
BLooper::MessageReceived(message);
|
||||||
break;
|
break;
|
||||||
|
@ -175,6 +189,24 @@ TeamDebugger::MessageReceived(BMessage* message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamDebugger::ThreadActionRequested(TeamWindow* window, thread_id threadID,
|
||||||
|
uint32 action)
|
||||||
|
{
|
||||||
|
BMessage message(action);
|
||||||
|
message.AddInt32("thread", threadID);
|
||||||
|
PostMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TeamDebugger::TeamWindowQuitRequested(TeamWindow* window)
|
||||||
|
{
|
||||||
|
// TODO:...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ status_t
|
/*static*/ status_t
|
||||||
TeamDebugger::_DebugEventListenerEntry(void* data)
|
TeamDebugger::_DebugEventListenerEntry(void* data)
|
||||||
{
|
{
|
||||||
|
@ -222,30 +254,43 @@ printf("TeamDebugger::_HandleDebuggerMessage(): %d\n", event->EventType());
|
||||||
switch (event->EventType()) {
|
switch (event->EventType()) {
|
||||||
case B_DEBUGGER_MESSAGE_THREAD_DEBUGGED:
|
case B_DEBUGGER_MESSAGE_THREAD_DEBUGGED:
|
||||||
printf("B_DEBUGGER_MESSAGE_THREAD_DEBUGGED: thread: %ld\n", event->Thread());
|
printf("B_DEBUGGER_MESSAGE_THREAD_DEBUGGED: thread: %ld\n", event->Thread());
|
||||||
|
handled = _HandleThreadDebugged(
|
||||||
|
dynamic_cast<ThreadDebuggedEvent*>(event));
|
||||||
break;
|
break;
|
||||||
case B_DEBUGGER_MESSAGE_DEBUGGER_CALL:
|
case B_DEBUGGER_MESSAGE_DEBUGGER_CALL:
|
||||||
printf("B_DEBUGGER_MESSAGE_DEBUGGER_CALL: thread: %ld\n", event->Thread());
|
printf("B_DEBUGGER_MESSAGE_DEBUGGER_CALL: thread: %ld\n", event->Thread());
|
||||||
|
handled = _HandleDebuggerCall(
|
||||||
|
dynamic_cast<DebuggerCallEvent*>(event));
|
||||||
break;
|
break;
|
||||||
case B_DEBUGGER_MESSAGE_BREAKPOINT_HIT:
|
case B_DEBUGGER_MESSAGE_BREAKPOINT_HIT:
|
||||||
printf("B_DEBUGGER_MESSAGE_BREAKPOINT_HIT: thread: %ld\n", event->Thread());
|
printf("B_DEBUGGER_MESSAGE_BREAKPOINT_HIT: thread: %ld\n", event->Thread());
|
||||||
|
handled = _HandleBreakpointHit(
|
||||||
|
dynamic_cast<BreakpointHitEvent*>(event));
|
||||||
break;
|
break;
|
||||||
case B_DEBUGGER_MESSAGE_WATCHPOINT_HIT:
|
case B_DEBUGGER_MESSAGE_WATCHPOINT_HIT:
|
||||||
printf("B_DEBUGGER_MESSAGE_WATCHPOINT_HIT: thread: %ld\n", event->Thread());
|
printf("B_DEBUGGER_MESSAGE_WATCHPOINT_HIT: thread: %ld\n", event->Thread());
|
||||||
|
handled = _HandleWatchpointHit(
|
||||||
|
dynamic_cast<WatchpointHitEvent*>(event));
|
||||||
break;
|
break;
|
||||||
case B_DEBUGGER_MESSAGE_SINGLE_STEP:
|
case B_DEBUGGER_MESSAGE_SINGLE_STEP:
|
||||||
printf("B_DEBUGGER_MESSAGE_SINGLE_STEP: thread: %ld\n", event->Thread());
|
printf("B_DEBUGGER_MESSAGE_SINGLE_STEP: thread: %ld\n", event->Thread());
|
||||||
|
handled = _HandleSingleStep(dynamic_cast<SingleStepEvent*>(event));
|
||||||
break;
|
break;
|
||||||
case B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED:
|
case B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED:
|
||||||
printf("B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED: thread: %ld\n", event->Thread());
|
printf("B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED: thread: %ld\n", event->Thread());
|
||||||
|
handled = _HandleExceptionOccurred(
|
||||||
|
dynamic_cast<ExceptionOccurredEvent*>(event));
|
||||||
break;
|
break;
|
||||||
// case B_DEBUGGER_MESSAGE_TEAM_CREATED:
|
// case B_DEBUGGER_MESSAGE_TEAM_CREATED:
|
||||||
//printf("B_DEBUGGER_MESSAGE_TEAM_CREATED: team: %ld\n", message.team_created.new_team);
|
//printf("B_DEBUGGER_MESSAGE_TEAM_CREATED: team: %ld\n", message.team_created.new_team);
|
||||||
// break;
|
// break;
|
||||||
case B_DEBUGGER_MESSAGE_TEAM_DELETED:
|
case B_DEBUGGER_MESSAGE_TEAM_DELETED:
|
||||||
|
// TODO: Handle!
|
||||||
printf("B_DEBUGGER_MESSAGE_TEAM_DELETED: team: %ld\n", event->Team());
|
printf("B_DEBUGGER_MESSAGE_TEAM_DELETED: team: %ld\n", event->Team());
|
||||||
break;
|
break;
|
||||||
case B_DEBUGGER_MESSAGE_TEAM_EXEC:
|
case B_DEBUGGER_MESSAGE_TEAM_EXEC:
|
||||||
printf("B_DEBUGGER_MESSAGE_TEAM_EXEC: team: %ld\n", event->Team());
|
printf("B_DEBUGGER_MESSAGE_TEAM_EXEC: team: %ld\n", event->Team());
|
||||||
|
// TODO: Handle!
|
||||||
break;
|
break;
|
||||||
case B_DEBUGGER_MESSAGE_THREAD_CREATED:
|
case B_DEBUGGER_MESSAGE_THREAD_CREATED:
|
||||||
handled = _HandleThreadCreated(
|
handled = _HandleThreadCreated(
|
||||||
|
@ -281,6 +326,70 @@ printf("B_DEBUGGER_MESSAGE_TEAM_EXEC: team: %ld\n", event->Team());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TeamDebugger::_HandleThreadStopped(thread_id threadID, CpuState* cpuState)
|
||||||
|
{
|
||||||
|
// get the thread
|
||||||
|
AutoLocker< ::Team> locker(fTeam);
|
||||||
|
::Thread* thread = fTeam->ThreadByID(threadID);
|
||||||
|
if (thread == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// update the thread state
|
||||||
|
thread->SetState(THREAD_STATE_STOPPED);
|
||||||
|
|
||||||
|
if (cpuState != NULL) {
|
||||||
|
thread->SetCpuState(cpuState);
|
||||||
|
} else {
|
||||||
|
// TODO: Trigger updating the CPU state!
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TeamDebugger::_HandleThreadDebugged(ThreadDebuggedEvent* event)
|
||||||
|
{
|
||||||
|
return _HandleThreadStopped(event->Thread(), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TeamDebugger::_HandleDebuggerCall(DebuggerCallEvent* event)
|
||||||
|
{
|
||||||
|
return _HandleThreadStopped(event->Thread(), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TeamDebugger::_HandleBreakpointHit(BreakpointHitEvent* event)
|
||||||
|
{
|
||||||
|
return _HandleThreadStopped(event->Thread(), event->GetCpuState());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TeamDebugger::_HandleWatchpointHit(WatchpointHitEvent* event)
|
||||||
|
{
|
||||||
|
return _HandleThreadStopped(event->Thread(), event->GetCpuState());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TeamDebugger::_HandleSingleStep(SingleStepEvent* event)
|
||||||
|
{
|
||||||
|
return _HandleThreadStopped(event->Thread(), event->GetCpuState());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TeamDebugger::_HandleExceptionOccurred(ExceptionOccurredEvent* event)
|
||||||
|
{
|
||||||
|
return _HandleThreadStopped(event->Thread(), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TeamDebugger::_HandleThreadCreated(ThreadCreatedEvent* event)
|
TeamDebugger::_HandleThreadCreated(ThreadCreatedEvent* event)
|
||||||
{
|
{
|
||||||
|
@ -339,3 +448,53 @@ TeamDebugger::_UpdateThreadState(::Thread* thread)
|
||||||
thread->SetState(newState);
|
thread->SetState(newState);
|
||||||
thread->SetCpuState(state);
|
thread->SetCpuState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamDebugger::_HandleThreadAction(thread_id threadID, uint32 action)
|
||||||
|
{
|
||||||
|
AutoLocker< ::Team> locker(fTeam);
|
||||||
|
|
||||||
|
::Thread* thread = fTeam->ThreadByID(threadID);
|
||||||
|
if (thread == NULL || thread->State() == THREAD_STATE_UNKNOWN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// When stop is requested, thread must be running, otherwise stopped.
|
||||||
|
if (action == MSG_THREAD_STOP
|
||||||
|
? thread->State() != THREAD_STATE_RUNNING
|
||||||
|
: thread->State() != THREAD_STATE_STOPPED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When continuing the thread update thread state before actually issuing
|
||||||
|
// the command, since we need to unlock.
|
||||||
|
if (action != MSG_THREAD_STOP)
|
||||||
|
thread->SetState(THREAD_STATE_RUNNING);
|
||||||
|
|
||||||
|
locker.Unlock();
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case MSG_THREAD_RUN:
|
||||||
|
printf("MSG_THREAD_RUN\n");
|
||||||
|
fDebuggerInterface->ContinueThread(threadID);
|
||||||
|
break;
|
||||||
|
case MSG_THREAD_STOP:
|
||||||
|
printf("MSG_THREAD_STOP\n");
|
||||||
|
fDebuggerInterface->StopThread(threadID);
|
||||||
|
break;
|
||||||
|
case MSG_THREAD_STEP_OVER:
|
||||||
|
printf("MSG_THREAD_STEP_OVER\n");
|
||||||
|
fDebuggerInterface->SingleStepThread(threadID);
|
||||||
|
break;
|
||||||
|
case MSG_THREAD_STEP_INTO:
|
||||||
|
printf("MSG_THREAD_STEP_INTO\n");
|
||||||
|
fDebuggerInterface->SingleStepThread(threadID);
|
||||||
|
break;
|
||||||
|
case MSG_THREAD_STEP_OUT:
|
||||||
|
printf("MSG_THREAD_STEP_OUT\n");
|
||||||
|
fDebuggerInterface->SingleStepThread(threadID);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// TODO: Handle stepping correctly!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,12 +34,32 @@ public:
|
||||||
private:
|
private:
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
|
// TeamWindow::Listener
|
||||||
|
virtual void ThreadActionRequested(TeamWindow* window,
|
||||||
|
thread_id threadID, uint32 action);
|
||||||
|
virtual bool TeamWindowQuitRequested(TeamWindow* window);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static status_t _DebugEventListenerEntry(void* data);
|
static status_t _DebugEventListenerEntry(void* data);
|
||||||
status_t _DebugEventListener();
|
status_t _DebugEventListener();
|
||||||
|
|
||||||
void _HandleDebuggerMessage(DebugEvent* event);
|
void _HandleDebuggerMessage(DebugEvent* event);
|
||||||
|
|
||||||
|
bool _HandleThreadStopped(thread_id threadID,
|
||||||
|
CpuState* cpuState);
|
||||||
|
|
||||||
|
bool _HandleThreadDebugged(
|
||||||
|
ThreadDebuggedEvent* event);
|
||||||
|
bool _HandleDebuggerCall(
|
||||||
|
DebuggerCallEvent* event);
|
||||||
|
bool _HandleBreakpointHit(
|
||||||
|
BreakpointHitEvent* event);
|
||||||
|
bool _HandleWatchpointHit(
|
||||||
|
WatchpointHitEvent* event);
|
||||||
|
bool _HandleSingleStep(
|
||||||
|
SingleStepEvent* event);
|
||||||
|
bool _HandleExceptionOccurred(
|
||||||
|
ExceptionOccurredEvent* event);
|
||||||
bool _HandleThreadCreated(
|
bool _HandleThreadCreated(
|
||||||
ThreadCreatedEvent* event);
|
ThreadCreatedEvent* event);
|
||||||
bool _HandleThreadDeleted(
|
bool _HandleThreadDeleted(
|
||||||
|
@ -51,6 +71,9 @@ private:
|
||||||
|
|
||||||
void _UpdateThreadState(::Thread* thread);
|
void _UpdateThreadState(::Thread* thread);
|
||||||
|
|
||||||
|
void _HandleThreadAction(thread_id threadID,
|
||||||
|
uint32 action);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::Team* fTeam;
|
::Team* fTeam;
|
||||||
TeamDebugModel* fDebugModel;
|
TeamDebugModel* fDebugModel;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "CpuState.h"
|
#include "CpuState.h"
|
||||||
#include "StackTrace.h"
|
#include "StackTrace.h"
|
||||||
|
#include "Team.h"
|
||||||
|
|
||||||
|
|
||||||
Thread::Thread(Team* team, thread_id threadID)
|
Thread::Thread(Team* team, thread_id threadID)
|
||||||
|
@ -56,6 +57,8 @@ Thread::SetState(uint32 state)
|
||||||
SetCpuState(NULL);
|
SetCpuState(NULL);
|
||||||
SetStackTrace(NULL);
|
SetStackTrace(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fTeam->NotifyThreadStateChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,8 +75,11 @@ Thread::SetCpuState(CpuState* state)
|
||||||
|
|
||||||
if (fCpuState != NULL)
|
if (fCpuState != NULL)
|
||||||
fCpuState->AddReference();
|
fCpuState->AddReference();
|
||||||
|
|
||||||
|
fTeam->NotifyThreadCpuStateChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Thread::SetStackTrace(StackTrace* trace)
|
Thread::SetStackTrace(StackTrace* trace)
|
||||||
{
|
{
|
||||||
|
@ -87,4 +93,6 @@ Thread::SetStackTrace(StackTrace* trace)
|
||||||
|
|
||||||
if (fStackTrace != NULL)
|
if (fStackTrace != NULL)
|
||||||
fStackTrace->AddReference();
|
fStackTrace->AddReference();
|
||||||
|
|
||||||
|
fTeam->NotifyThreadStackTraceChanged(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,26 @@ DebuggerInterface::ContinueThread(thread_id thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DebuggerInterface::StopThread(thread_id thread)
|
||||||
|
{
|
||||||
|
return debug_thread(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DebuggerInterface::SingleStepThread(thread_id thread)
|
||||||
|
{
|
||||||
|
debug_nub_continue_thread continueMessage;
|
||||||
|
continueMessage.thread = thread;
|
||||||
|
continueMessage.handle_event = B_THREAD_DEBUG_HANDLE_EVENT;
|
||||||
|
continueMessage.single_step = true;
|
||||||
|
|
||||||
|
return write_port(fNubPort, B_DEBUG_MESSAGE_CONTINUE_THREAD,
|
||||||
|
&continueMessage, sizeof(continueMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DebuggerInterface::GetThreadInfos(BObjectList<ThreadInfo>& infos)
|
DebuggerInterface::GetThreadInfos(BObjectList<ThreadInfo>& infos)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,8 @@ public:
|
||||||
virtual status_t SetTeamDebuggingFlags(uint32 flags);
|
virtual status_t SetTeamDebuggingFlags(uint32 flags);
|
||||||
|
|
||||||
virtual status_t ContinueThread(thread_id thread);
|
virtual status_t ContinueThread(thread_id thread);
|
||||||
|
virtual status_t StopThread(thread_id thread);
|
||||||
|
virtual status_t SingleStepThread(thread_id thread);
|
||||||
|
|
||||||
virtual status_t GetThreadInfos(BObjectList<ThreadInfo>& infos);
|
virtual status_t GetThreadInfos(BObjectList<ThreadInfo>& infos);
|
||||||
virtual status_t GetImageInfos(BObjectList<ImageInfo>& infos);
|
virtual status_t GetImageInfos(BObjectList<ImageInfo>& infos);
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include <SplitView.h>
|
#include <SplitView.h>
|
||||||
#include <TextView.h>
|
#include <TextView.h>
|
||||||
|
|
||||||
|
#include <AutoLocker.h>
|
||||||
|
|
||||||
#include "ImageListView.h"
|
#include "ImageListView.h"
|
||||||
#include "MessageCodes.h"
|
#include "MessageCodes.h"
|
||||||
#include "TeamDebugModel.h"
|
#include "TeamDebugModel.h"
|
||||||
|
@ -42,11 +44,14 @@ TeamWindow::TeamWindow(TeamDebugModel* debugModel, Listener* listener)
|
||||||
if (team->ID() >= 0)
|
if (team->ID() >= 0)
|
||||||
name << " (" << team->ID() << ")";
|
name << " (" << team->ID() << ")";
|
||||||
SetTitle(name.String());
|
SetTitle(name.String());
|
||||||
|
|
||||||
|
team->AddListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TeamWindow::~TeamWindow()
|
TeamWindow::~TeamWindow()
|
||||||
{
|
{
|
||||||
|
fDebugModel->GetTeam()->RemoveListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,17 +76,28 @@ TeamWindow::MessageReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
case MSG_THREAD_RUN:
|
case MSG_THREAD_RUN:
|
||||||
printf("MSG_THREAD_RUN\n");
|
case MSG_THREAD_STOP:
|
||||||
break;
|
|
||||||
case MSG_THREAD_STEP_OVER:
|
case MSG_THREAD_STEP_OVER:
|
||||||
printf("MSG_THREAD_STEP_OVER\n");
|
|
||||||
break;
|
|
||||||
case MSG_THREAD_STEP_INTO:
|
case MSG_THREAD_STEP_INTO:
|
||||||
printf("MSG_THREAD_STEP_INTO\n");
|
|
||||||
break;
|
|
||||||
case MSG_THREAD_STEP_OUT:
|
case MSG_THREAD_STEP_OUT:
|
||||||
printf("MSG_THREAD_STEP_OUT\n");
|
if (fActiveThread != NULL) {
|
||||||
|
fListener->ThreadActionRequested(this, fActiveThread->ID(),
|
||||||
|
message->what);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSG_THREAD_STATE_CHANGED:
|
||||||
|
{
|
||||||
|
int32 threadID;
|
||||||
|
if (message->FindInt32("thread", &threadID) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
_HandleThreadStateChanged(threadID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// case MSG_THREAD_CPU_STATE_CHANGED:
|
||||||
|
// case MSG_THREAD_STACK_TRACE_CHANGED:
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BWindow::MessageReceived(message);
|
BWindow::MessageReceived(message);
|
||||||
break;
|
break;
|
||||||
|
@ -103,6 +119,33 @@ TeamWindow::ThreadSelectionChanged(::Thread* thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamWindow::ThreadStateChanged(const Team::ThreadEvent& event)
|
||||||
|
{
|
||||||
|
BMessage message(MSG_THREAD_STATE_CHANGED);
|
||||||
|
message.AddInt32("thread", event.GetThread()->ID());
|
||||||
|
PostMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamWindow::ThreadCpuStateChanged(const Team::ThreadEvent& event)
|
||||||
|
{
|
||||||
|
// BMessage message(MSG_THREAD_CPU_STATE_CHANGED);
|
||||||
|
// message.AddInt32("thread", event.GetThread()->ID());
|
||||||
|
// PostMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamWindow::ThreadStackTraceChanged(const Team::ThreadEvent& event)
|
||||||
|
{
|
||||||
|
// BMessage message(MSG_THREAD_STACK_TRACE_CHANGED);
|
||||||
|
// message.AddInt32("thread", event.GetThread()->ID());
|
||||||
|
// PostMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TeamWindow::_Init()
|
TeamWindow::_Init()
|
||||||
{
|
{
|
||||||
|
@ -155,6 +198,7 @@ TeamWindow::_Init()
|
||||||
fRunButton->SetTarget(this);
|
fRunButton->SetTarget(this);
|
||||||
fStepOutButton->SetTarget(this);
|
fStepOutButton->SetTarget(this);
|
||||||
|
|
||||||
|
AutoLocker<TeamDebugModel> locker(fDebugModel);
|
||||||
_UpdateRunButtons();
|
_UpdateRunButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +211,7 @@ TeamWindow::_SetActiveThread(::Thread* thread)
|
||||||
|
|
||||||
fActiveThread = thread;
|
fActiveThread = thread;
|
||||||
|
|
||||||
|
AutoLocker<TeamDebugModel> locker(fDebugModel);
|
||||||
_UpdateRunButtons();
|
_UpdateRunButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +231,7 @@ TeamWindow::_UpdateRunButtons()
|
||||||
break;
|
break;
|
||||||
case THREAD_STATE_RUNNING:
|
case THREAD_STATE_RUNNING:
|
||||||
fRunButton->SetLabel("Stop");
|
fRunButton->SetLabel("Stop");
|
||||||
|
fRunButton->SetMessage(new BMessage(MSG_THREAD_STOP));
|
||||||
fRunButton->SetEnabled(true);
|
fRunButton->SetEnabled(true);
|
||||||
fStepOverButton->SetEnabled(false);
|
fStepOverButton->SetEnabled(false);
|
||||||
fStepIntoButton->SetEnabled(false);
|
fStepIntoButton->SetEnabled(false);
|
||||||
|
@ -193,6 +239,7 @@ TeamWindow::_UpdateRunButtons()
|
||||||
break;
|
break;
|
||||||
case THREAD_STATE_STOPPED:
|
case THREAD_STATE_STOPPED:
|
||||||
fRunButton->SetLabel("Run");
|
fRunButton->SetLabel("Run");
|
||||||
|
fRunButton->SetMessage(new BMessage(MSG_THREAD_RUN));
|
||||||
fRunButton->SetEnabled(true);
|
fRunButton->SetEnabled(true);
|
||||||
fStepOverButton->SetEnabled(true);
|
fStepOverButton->SetEnabled(true);
|
||||||
fStepIntoButton->SetEnabled(true);
|
fStepIntoButton->SetEnabled(true);
|
||||||
|
@ -202,16 +249,21 @@ TeamWindow::_UpdateRunButtons()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamWindow::_HandleThreadStateChanged(thread_id threadID)
|
||||||
|
{
|
||||||
|
// ATM we're only interested in the currently selected thread
|
||||||
|
if (fActiveThread == NULL || threadID != fActiveThread->ID())
|
||||||
|
return;
|
||||||
|
|
||||||
|
AutoLocker<TeamDebugModel> locker(fDebugModel);
|
||||||
|
_UpdateRunButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - Listener
|
// #pragma mark - Listener
|
||||||
|
|
||||||
|
|
||||||
TeamWindow::Listener::~Listener()
|
TeamWindow::Listener::~Listener()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
TeamWindow::Listener::TeamWindowQuitRequested(TeamWindow* window)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,17 +8,18 @@
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "Team.h"
|
||||||
#include "ThreadListView.h"
|
#include "ThreadListView.h"
|
||||||
|
|
||||||
|
|
||||||
class BButton;
|
class BButton;
|
||||||
class BTabView;
|
class BTabView;
|
||||||
class ImageListView;
|
class ImageListView;
|
||||||
class Team;
|
|
||||||
class TeamDebugModel;
|
class TeamDebugModel;
|
||||||
|
|
||||||
|
|
||||||
class TeamWindow : public BWindow, private ThreadListView::Listener {
|
class TeamWindow : public BWindow, private ThreadListView::Listener,
|
||||||
|
Team::Listener {
|
||||||
public:
|
public:
|
||||||
class Listener;
|
class Listener;
|
||||||
|
|
||||||
|
@ -38,11 +39,21 @@ private:
|
||||||
// ThreadListView::Listener
|
// ThreadListView::Listener
|
||||||
virtual void ThreadSelectionChanged(::Thread* thread);
|
virtual void ThreadSelectionChanged(::Thread* thread);
|
||||||
|
|
||||||
|
// Team::Listener
|
||||||
|
virtual void ThreadStateChanged(
|
||||||
|
const Team::ThreadEvent& event);
|
||||||
|
virtual void ThreadCpuStateChanged(
|
||||||
|
const Team::ThreadEvent& event);
|
||||||
|
virtual void ThreadStackTraceChanged(
|
||||||
|
const Team::ThreadEvent& event);
|
||||||
|
|
||||||
void _Init();
|
void _Init();
|
||||||
|
|
||||||
void _SetActiveThread(::Thread* thread);
|
void _SetActiveThread(::Thread* thread);
|
||||||
void _UpdateRunButtons();
|
void _UpdateRunButtons();
|
||||||
|
|
||||||
|
void _HandleThreadStateChanged(thread_id threadID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TeamDebugModel* fDebugModel;
|
TeamDebugModel* fDebugModel;
|
||||||
::Thread* fActiveThread;
|
::Thread* fActiveThread;
|
||||||
|
@ -61,7 +72,9 @@ class TeamWindow::Listener {
|
||||||
public:
|
public:
|
||||||
virtual ~Listener();
|
virtual ~Listener();
|
||||||
|
|
||||||
virtual bool TeamWindowQuitRequested(TeamWindow* window);
|
virtual void ThreadActionRequested(TeamWindow* window,
|
||||||
|
thread_id threadID, uint32 action) = 0;
|
||||||
|
virtual bool TeamWindowQuitRequested(TeamWindow* window) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue