[Haiku-commits] r31221 - haiku/trunk/src/apps/debugger
bonefish at BerliOS
bonefish at mail.berlios.de
Wed Jun 24 03:46:40 CEST 2009
Author: bonefish
Date: 2009-06-24 03:46:38 +0200 (Wed, 24 Jun 2009)
New Revision: 31221
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31221&view=rev
Added:
haiku/trunk/src/apps/debugger/ThreadHandler.cpp
haiku/trunk/src/apps/debugger/ThreadHandler.h
Modified:
haiku/trunk/src/apps/debugger/Jamfile
haiku/trunk/src/apps/debugger/Jobs.cpp
haiku/trunk/src/apps/debugger/Jobs.h
haiku/trunk/src/apps/debugger/TeamDebugger.cpp
haiku/trunk/src/apps/debugger/TeamDebugger.h
Log:
* Moved all handling of threads from TeamDebugger into new class ThreadHandler.
* Added new job to get the initial state of a thread.
* Now we also get the states of new threads correctly.
Modified: haiku/trunk/src/apps/debugger/Jamfile
===================================================================
--- haiku/trunk/src/apps/debugger/Jamfile 2009-06-24 00:25:21 UTC (rev 31220)
+++ haiku/trunk/src/apps/debugger/Jamfile 2009-06-24 01:46:38 UTC (rev 31221)
@@ -25,6 +25,7 @@
# ElfFile.cpp
Jobs.cpp
TeamDebugger.cpp
+ ThreadHandler.cpp
Worker.cpp
# arch
Modified: haiku/trunk/src/apps/debugger/Jobs.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/Jobs.cpp 2009-06-24 00:25:21 UTC (rev 31220)
+++ haiku/trunk/src/apps/debugger/Jobs.cpp 2009-06-24 01:46:38 UTC (rev 31221)
@@ -22,6 +22,56 @@
#include "Thread.h"
+// #pragma mark - GetThreadStateJob
+
+
+GetThreadStateJob::GetThreadStateJob(DebuggerInterface* debuggerInterface,
+ Thread* thread)
+ :
+ fDebuggerInterface(debuggerInterface),
+ fThread(thread)
+{
+ fThread->AddReference();
+}
+
+
+GetThreadStateJob::~GetThreadStateJob()
+{
+ fThread->RemoveReference();
+}
+
+
+JobKey
+GetThreadStateJob::Key() const
+{
+ return JobKey(fThread, JOB_TYPE_GET_THREAD_STATE);
+}
+
+
+status_t
+GetThreadStateJob::Do()
+{
+ CpuState* state = NULL;
+ status_t error = fDebuggerInterface->GetCpuState(fThread->ID(), state);
+ Reference<CpuState> reference(state, true);
+
+ AutoLocker<Team> locker(fThread->GetTeam());
+
+ if (fThread->State() != THREAD_STATE_UNKNOWN)
+ return B_OK;
+
+ if (error == B_OK) {
+ fThread->SetState(THREAD_STATE_STOPPED);
+ fThread->SetCpuState(state);
+ } else if (error == B_BAD_THREAD_STATE) {
+ fThread->SetState(THREAD_STATE_RUNNING);
+ } else
+ return error;
+
+ return B_OK;
+}
+
+
// #pragma mark - GetCpuStateJob
Modified: haiku/trunk/src/apps/debugger/Jobs.h
===================================================================
--- haiku/trunk/src/apps/debugger/Jobs.h 2009-06-24 00:25:21 UTC (rev 31220)
+++ haiku/trunk/src/apps/debugger/Jobs.h 2009-06-24 01:46:38 UTC (rev 31221)
@@ -20,6 +20,7 @@
// job types
enum {
+ JOB_TYPE_GET_THREAD_STATE,
JOB_TYPE_GET_CPU_STATE,
JOB_TYPE_GET_STACK_TRACE,
JOB_TYPE_LOAD_IMAGE_DEBUG_INFO,
@@ -27,6 +28,22 @@
};
+class GetThreadStateJob : public Job {
+public:
+ GetThreadStateJob(
+ DebuggerInterface* debuggerInterface,
+ Thread* thread);
+ virtual ~GetThreadStateJob();
+
+ virtual JobKey Key() const;
+ virtual status_t Do();
+
+private:
+ DebuggerInterface* fDebuggerInterface;
+ Thread* fThread;
+};
+
+
class GetCpuStateJob : public Job {
public:
GetCpuStateJob(
Modified: haiku/trunk/src/apps/debugger/TeamDebugger.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/TeamDebugger.cpp 2009-06-24 00:25:21 UTC (rev 31220)
+++ haiku/trunk/src/apps/debugger/TeamDebugger.cpp 2009-06-24 01:46:38 UTC (rev 31221)
@@ -59,6 +59,13 @@
if (fDebugEventListener >= 0)
wait_for_thread(fDebugEventListener, NULL);
+ ThreadHandler* threadHandler = fThreadHandlers.Clear(true);
+ while (threadHandler != NULL) {
+ ThreadHandler* next = threadHandler->fNext;
+ threadHandler->RemoveReference();
+ threadHandler = next;
+ }
+
delete fDebuggerInterface;
delete fWorker;
delete fDebugModel;
@@ -92,6 +99,11 @@
fTeam->AddListener(this);
+ // init thread handler table
+ error = fThreadHandlers.Init();
+ if (error != B_OK)
+ return error;
+
// create our worker
fWorker = new(std::nothrow) Worker;
if (fWorker == NULL)
@@ -136,7 +148,14 @@
if (error != B_OK)
return error;
- _UpdateThreadState(thread);
+ ThreadHandler* handler = new(std::nothrow) ThreadHandler(
+ fDebugModel, thread, fWorker, fDebuggerInterface);
+ if (handler == NULL)
+ return B_NO_MEMORY;
+
+ fThreadHandlers.Insert(handler);
+
+ handler->Init();
}
}
@@ -204,7 +223,10 @@
if (message->FindInt32("thread", &threadID) != B_OK)
break;
- _HandleThreadAction(threadID, message->what);
+ if (ThreadHandler* handler = _GetThreadHandler(threadID)) {
+ handler->HandleThreadAction(message->what);
+ handler->RemoveReference();
+ }
break;
}
@@ -232,7 +254,10 @@
if (message->FindInt32("thread", &threadID) != B_OK)
break;
- _HandleThreadStateChanged(threadID);
+ if (ThreadHandler* handler = _GetThreadHandler(threadID)) {
+ handler->HandleThreadStateChanged();
+ handler->RemoveReference();
+ }
break;
}
case MSG_THREAD_CPU_STATE_CHANGED:
@@ -241,7 +266,10 @@
if (message->FindInt32("thread", &threadID) != B_OK)
break;
- _HandleCpuStateChanged(threadID);
+ if (ThreadHandler* handler = _GetThreadHandler(threadID)) {
+ handler->HandleCpuStateChanged();
+ handler->RemoveReference();
+ }
break;
}
case MSG_THREAD_STACK_TRACE_CHANGED:
@@ -250,7 +278,10 @@
if (message->FindInt32("thread", &threadID) != B_OK)
break;
- _HandleStackTraceChanged(threadID);
+ if (ThreadHandler* handler = _GetThreadHandler(threadID)) {
+ handler->HandleStackTraceChanged();
+ handler->RemoveReference();
+ }
break;
}
@@ -448,35 +479,51 @@
printf("TeamDebugger::_HandleDebuggerMessage(): %d\n", event->EventType());
bool handled = false;
+ ThreadHandler* handler = _GetThreadHandler(event->Thread());
+ Reference<ThreadHandler> handlerReference(handler);
+
switch (event->EventType()) {
case B_DEBUGGER_MESSAGE_THREAD_DEBUGGED:
printf("B_DEBUGGER_MESSAGE_THREAD_DEBUGGED: thread: %ld\n", event->Thread());
- handled = _HandleThreadDebugged(
- dynamic_cast<ThreadDebuggedEvent*>(event));
+ if (handler != NULL) {
+ handled = handler->HandleThreadDebugged(
+ dynamic_cast<ThreadDebuggedEvent*>(event));
+ }
break;
case B_DEBUGGER_MESSAGE_DEBUGGER_CALL:
printf("B_DEBUGGER_MESSAGE_DEBUGGER_CALL: thread: %ld\n", event->Thread());
- handled = _HandleDebuggerCall(
- dynamic_cast<DebuggerCallEvent*>(event));
+ if (handler != NULL) {
+ handled = handler->HandleDebuggerCall(
+ dynamic_cast<DebuggerCallEvent*>(event));
+ }
break;
case B_DEBUGGER_MESSAGE_BREAKPOINT_HIT:
printf("B_DEBUGGER_MESSAGE_BREAKPOINT_HIT: thread: %ld\n", event->Thread());
- handled = _HandleBreakpointHit(
- dynamic_cast<BreakpointHitEvent*>(event));
+ if (handler != NULL) {
+ handled = handler->HandleBreakpointHit(
+ dynamic_cast<BreakpointHitEvent*>(event));
+ }
break;
case B_DEBUGGER_MESSAGE_WATCHPOINT_HIT:
printf("B_DEBUGGER_MESSAGE_WATCHPOINT_HIT: thread: %ld\n", event->Thread());
- handled = _HandleWatchpointHit(
- dynamic_cast<WatchpointHitEvent*>(event));
+ if (handler != NULL) {
+ handled = handler->HandleWatchpointHit(
+ dynamic_cast<WatchpointHitEvent*>(event));
+ }
break;
case B_DEBUGGER_MESSAGE_SINGLE_STEP:
printf("B_DEBUGGER_MESSAGE_SINGLE_STEP: thread: %ld\n", event->Thread());
- handled = _HandleSingleStep(dynamic_cast<SingleStepEvent*>(event));
+ if (handler != NULL) {
+ handled = handler->HandleSingleStep(
+ dynamic_cast<SingleStepEvent*>(event));
+ }
break;
case B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED:
printf("B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED: thread: %ld\n", event->Thread());
- handled = _HandleExceptionOccurred(
- dynamic_cast<ExceptionOccurredEvent*>(event));
+ if (handler != NULL) {
+ handled = handler->HandleExceptionOccurred(
+ dynamic_cast<ExceptionOccurredEvent*>(event));
+ }
break;
// case B_DEBUGGER_MESSAGE_TEAM_CREATED:
//printf("B_DEBUGGER_MESSAGE_TEAM_CREATED: team: %ld\n", message.team_created.new_team);
@@ -524,63 +571,6 @@
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;
-
- _SetThreadState(thread, THREAD_STATE_STOPPED, cpuState);
-
- 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
TeamDebugger::_HandleThreadCreated(ThreadCreatedEvent* event)
{
AutoLocker< ::Team> locker(fTeam);
@@ -588,9 +578,18 @@
ThreadInfo info;
status_t error = fDebuggerInterface->GetThreadInfo(event->NewThread(),
info);
- if (error == B_OK)
- fTeam->AddThread(info);
+ if (error == B_OK) {
+ ::Thread* thread;
+ fTeam->AddThread(info, &thread);
+ ThreadHandler* handler = new(std::nothrow) ThreadHandler(
+ fDebugModel, thread, fWorker, fDebuggerInterface);
+ if (handler != NULL) {
+ fThreadHandlers.Insert(handler);
+ handler->Init();
+ }
+ }
+
return false;
}
@@ -599,6 +598,10 @@
TeamDebugger::_HandleThreadDeleted(ThreadDeletedEvent* event)
{
AutoLocker< ::Team> locker(fTeam);
+ if (ThreadHandler* handler = fThreadHandlers.Lookup(event->Thread())) {
+ fThreadHandlers.Remove(handler);
+ handler->RemoveReference();
+ }
fTeam->RemoveThread(event->Thread());
return false;
}
@@ -622,32 +625,6 @@
}
-void
-TeamDebugger::_UpdateThreadState(::Thread* thread)
-{
- CpuState* cpuState = NULL;
- status_t error = fDebuggerInterface->GetCpuState(thread->ID(), cpuState);
-
- uint32 newState = THREAD_STATE_UNKNOWN;
- if (error == B_OK) {
- newState = THREAD_STATE_STOPPED;
- cpuState->RemoveReference();
- } else if (error == B_BAD_THREAD_STATE)
- newState = THREAD_STATE_RUNNING;
-
- _SetThreadState(thread, newState, cpuState);
-}
-
-
-void
-TeamDebugger::_SetThreadState(::Thread* thread, uint32 state,
- CpuState* cpuState)
-{
- thread->SetState(state);
- thread->SetCpuState(cpuState);
-}
-
-
status_t
TeamDebugger::_SetUserBreakpoint(target_addr_t address, bool enabled)
{
@@ -716,56 +693,6 @@
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)
- _SetThreadState(thread, THREAD_STATE_RUNNING, NULL);
-
- 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!
- }
-}
-
-
-void
TeamDebugger::_HandleSetUserBreakpoint(target_addr_t address, bool enabled)
{
printf("TeamDebugger::_HandleSetUserBreakpoint(%#llx, %d)\n", address, enabled);
@@ -806,59 +733,19 @@
}
-void
-TeamDebugger::_HandleThreadStateChanged(thread_id threadID)
+ThreadHandler*
+TeamDebugger::_GetThreadHandler(thread_id threadID)
{
- AutoLocker< ::Team> teamLocker(fTeam);
+ AutoLocker<TeamDebugModel> locker(fDebugModel);
- ::Thread* thread = fTeam->ThreadByID(threadID);
- if (thread == NULL)
- return;
-
- // cancel jobs for this thread
- fWorker->AbortJob(JobKey(thread, JOB_TYPE_GET_CPU_STATE));
- fWorker->AbortJob(JobKey(thread, JOB_TYPE_GET_STACK_TRACE));
-
- // If the thread is stopped and has no CPU state yet, schedule a job.
- if (thread->State() == THREAD_STATE_STOPPED
- && thread->GetCpuState() == NULL) {
- fWorker->ScheduleJob(
- new(std::nothrow) GetCpuStateJob(fDebuggerInterface, thread),
- this);
- }
+ ThreadHandler* handler = fThreadHandlers.Lookup(threadID);
+ if (handler != NULL)
+ handler->AddReference();
+ return handler;
}
void
-TeamDebugger::_HandleCpuStateChanged(thread_id threadID)
-{
- AutoLocker< ::Team> teamLocker(fTeam);
-
- ::Thread* thread = fTeam->ThreadByID(threadID);
- if (thread == NULL)
- return;
-
- // cancel stack trace job for this thread
- fWorker->AbortJob(JobKey(thread, JOB_TYPE_GET_STACK_TRACE));
-
- // If the thread has a CPU state, but no stack trace yet, schedule a job.
- if (thread->GetCpuState() != NULL && thread->GetStackTrace() == NULL) {
- fWorker->ScheduleJob(
- new(std::nothrow) GetStackTraceJob(fDebuggerInterface,
- fDebuggerInterface->GetArchitecture(), thread),
- this);
- }
-}
-
-
-void
-TeamDebugger::_HandleStackTraceChanged(thread_id threadID)
-{
-printf("TeamDebugger::_HandleStackTraceChanged()\n");
-}
-
-
-void
TeamDebugger::_NotifyUser(const char* title, const char* text,...)
{
// print the message
Modified: haiku/trunk/src/apps/debugger/TeamDebugger.h
===================================================================
--- haiku/trunk/src/apps/debugger/TeamDebugger.h 2009-06-24 00:25:21 UTC (rev 31220)
+++ haiku/trunk/src/apps/debugger/TeamDebugger.h 2009-06-24 01:46:38 UTC (rev 31221)
@@ -13,6 +13,7 @@
#include "DebugEvent.h"
#include "Team.h"
#include "TeamWindow.h"
+#include "ThreadHandler.h"
#include "Worker.h"
@@ -66,21 +67,6 @@
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(
ThreadCreatedEvent* event);
bool _HandleThreadDeleted(
@@ -90,24 +76,18 @@
bool _HandleImageDeleted(
ImageDeletedEvent* event);
- void _UpdateThreadState(::Thread* thread);
- void _SetThreadState(::Thread* thread, uint32 state,
- CpuState* cpuState);
status_t _SetUserBreakpoint(target_addr_t address,
bool enabled);
- void _HandleThreadAction(thread_id threadID,
- uint32 action);
void _HandleSetUserBreakpoint(target_addr_t address,
bool enabled);
void _HandleClearUserBreakpoint(
target_addr_t address);
- void _HandleThreadStateChanged(thread_id threadID);
- void _HandleCpuStateChanged(thread_id threadID);
- void _HandleStackTraceChanged(thread_id threadID);
+ ThreadHandler* _GetThreadHandler(thread_id threadID);
+
void _NotifyUser(const char* title,
const char* text,...);
@@ -116,7 +96,8 @@
::Team* fTeam;
TeamDebugModel* fDebugModel;
team_id fTeamID;
- port_id fNubPort;
+ ThreadHandlerTable fThreadHandlers;
+ // protected by the team lock
DebuggerInterface* fDebuggerInterface;
Worker* fWorker;
thread_id fDebugEventListener;
Added: haiku/trunk/src/apps/debugger/ThreadHandler.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/ThreadHandler.cpp 2009-06-24 00:25:21 UTC (rev 31220)
+++ haiku/trunk/src/apps/debugger/ThreadHandler.cpp 2009-06-24 01:46:38 UTC (rev 31221)
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold at gmx.de.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "ThreadHandler.h"
+
+#include <stdio.h>
+
+#include <new>
+
+#include <AutoLocker.h>
+
+#include "CpuState.h"
+#include "DebuggerInterface.h"
+#include "Jobs.h"
+#include "MessageCodes.h"
+#include "Team.h"
+#include "TeamDebugModel.h"
+#include "Worker.h"
+
+
+ThreadHandler::ThreadHandler(TeamDebugModel* debugModel, Thread* thread,
+ Worker* worker, DebuggerInterface* debuggerInterface)
+ :
+ fDebugModel(debugModel),
+ fThread(thread),
+ fWorker(worker),
+ fDebuggerInterface(debuggerInterface)
+{
+}
+
+
+ThreadHandler::~ThreadHandler()
+{
+}
+
+
+void
+ThreadHandler::Init()
+{
+ fWorker->ScheduleJob(new(std::nothrow) GetThreadStateJob(fDebuggerInterface,
+ fThread));
+}
+
+
+bool
+ThreadHandler::HandleThreadDebugged(ThreadDebuggedEvent* event)
+{
+ return _HandleThreadStopped(NULL);
+}
+
+
+bool
+ThreadHandler::HandleDebuggerCall(DebuggerCallEvent* event)
+{
+ return _HandleThreadStopped(NULL);
+}
+
+
+bool
+ThreadHandler::HandleBreakpointHit(BreakpointHitEvent* event)
+{
+ return _HandleThreadStopped(event->GetCpuState());
+}
+
+
+bool
+ThreadHandler::HandleWatchpointHit(WatchpointHitEvent* event)
+{
+ return _HandleThreadStopped(event->GetCpuState());
+}
+
+
+bool
+ThreadHandler::HandleSingleStep(SingleStepEvent* event)
+{
+ return _HandleThreadStopped(event->GetCpuState());
+}
+
+
+bool
+ThreadHandler::HandleExceptionOccurred(ExceptionOccurredEvent* event)
+{
+ return _HandleThreadStopped(NULL);
+}
+
+
+void
+ThreadHandler::HandleThreadAction(uint32 action)
+{
+ AutoLocker<TeamDebugModel> locker(fDebugModel);
+
+ if (fThread->State() == THREAD_STATE_UNKNOWN)
+ return;
+
+ // When stop is requested, thread must be running, otherwise stopped.
+ if (action == MSG_THREAD_STOP
+ ? fThread->State() != THREAD_STATE_RUNNING
+ : fThread->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)
+ _SetThreadState(THREAD_STATE_RUNNING, NULL);
+
+ 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!
+ }
+}
+
+
+void
+ThreadHandler::HandleThreadStateChanged()
+{
+ AutoLocker<TeamDebugModel> locker(fDebugModel);
+
+ // cancel jobs for this thread
+ fWorker->AbortJob(JobKey(fThread, JOB_TYPE_GET_CPU_STATE));
+ fWorker->AbortJob(JobKey(fThread, JOB_TYPE_GET_STACK_TRACE));
+
+ // If the thread is stopped and has no CPU state yet, schedule a job.
+ if (fThread->State() == THREAD_STATE_STOPPED
+ && fThread->GetCpuState() == NULL) {
+ fWorker->ScheduleJob(
+ new(std::nothrow) GetCpuStateJob(fDebuggerInterface, fThread));
+ }
+}
+
+
+void
+ThreadHandler::HandleCpuStateChanged()
+{
+ AutoLocker<TeamDebugModel> locker(fDebugModel);
+
+ // cancel stack trace job for this thread
+ fWorker->AbortJob(JobKey(fThread, JOB_TYPE_GET_STACK_TRACE));
+
+ // If the thread has a CPU state, but no stack trace yet, schedule a job.
+ if (fThread->GetCpuState() != NULL && fThread->GetStackTrace() == NULL) {
+ fWorker->ScheduleJob(
+ new(std::nothrow) GetStackTraceJob(fDebuggerInterface,
+ fDebuggerInterface->GetArchitecture(), fThread));
+ }
+}
+
+
+void
+ThreadHandler::HandleStackTraceChanged()
+{
+printf("ThreadHandler::_HandleStackTraceChanged()\n");
+}
+
+
+bool
+ThreadHandler::_HandleThreadStopped(CpuState* cpuState)
+{
+ AutoLocker<TeamDebugModel> locker(fDebugModel);
+
+ _SetThreadState(THREAD_STATE_STOPPED, cpuState);
+
+ return true;
+}
+
+
+void
+ThreadHandler::_SetThreadState(uint32 state, CpuState* cpuState)
+{
+ fThread->SetState(state);
+ fThread->SetCpuState(cpuState);
+}
Added: haiku/trunk/src/apps/debugger/ThreadHandler.h
===================================================================
--- haiku/trunk/src/apps/debugger/ThreadHandler.h 2009-06-24 00:25:21 UTC (rev 31220)
+++ haiku/trunk/src/apps/debugger/ThreadHandler.h 2009-06-24 01:46:38 UTC (rev 31221)
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold at gmx.de.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef THREAD_HANDLER_H
+#define THREAD_HANDLER_H
+
+#include <Referenceable.h>
+#include <util/OpenHashTable.h>
+
+#include "DebugEvent.h"
+#include "Thread.h"
+
+
+class DebuggerInterface;
+class TeamDebugModel;
+class Worker;
+
+
+class ThreadHandler : public Referenceable,
+ public HashTableLink<ThreadHandler> {
+public:
+ ThreadHandler(TeamDebugModel* debugModel,
+ Thread* thread, Worker* worker,
+ DebuggerInterface* debuggerInterface);
+ ~ThreadHandler();
+
+ void Init();
+
+ thread_id ThreadID() const { return fThread->ID(); }
+ Thread* GetThread() const { return fThread; }
+
+ bool HandleThreadDebugged(
+ ThreadDebuggedEvent* event);
+ bool HandleDebuggerCall(
+ DebuggerCallEvent* event);
+ bool HandleBreakpointHit(
+ BreakpointHitEvent* event);
+ bool HandleWatchpointHit(
+ WatchpointHitEvent* event);
+ bool HandleSingleStep(
+ SingleStepEvent* event);
+ bool HandleExceptionOccurred(
+ ExceptionOccurredEvent* event);
+
+ void HandleThreadAction(uint32 action);
+
+ void HandleThreadStateChanged();
+ void HandleCpuStateChanged();
+ void HandleStackTraceChanged();
+
+private:
+ bool _HandleThreadStopped(CpuState* cpuState);
+
+ void _SetThreadState(uint32 state,
+ CpuState* cpuState);
+
+private:
+ TeamDebugModel* fDebugModel;
+ Thread* fThread;
+ Worker* fWorker;
+ DebuggerInterface* fDebuggerInterface;
+};
+
+
+struct ThreadHandlerHashDefinition {
+ typedef thread_id KeyType;
+ typedef ThreadHandler ValueType;
+
+ size_t HashKey(thread_id key) const
+ {
+ return (size_t)key;
+ }
+
+ size_t Hash(const ThreadHandler* value) const
+ {
+ return HashKey(value->ThreadID());
+ }
+
+ bool Compare(thread_id key, ThreadHandler* value) const
+ {
+ return value->ThreadID() == key;
+ }
+
+ HashTableLink<ThreadHandler>* GetLink(ThreadHandler* value) const
+ {
+ return value;
+ }
+};
+
+typedef OpenHashTable<ThreadHandlerHashDefinition> ThreadHandlerTable;
+
+
+#endif // THREAD_HANDLER_H
More information about the Haiku-commits
mailing list