2009-06-24 01:46:38 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*/
|
|
|
|
#ifndef THREAD_HANDLER_H
|
|
|
|
#define THREAD_HANDLER_H
|
|
|
|
|
2009-07-22 19:20:06 +00:00
|
|
|
|
2009-06-24 01:46:38 +00:00
|
|
|
#include <Referenceable.h>
|
|
|
|
#include <util/OpenHashTable.h>
|
|
|
|
|
2009-06-25 23:51:09 +00:00
|
|
|
#include "Breakpoint.h"
|
2009-06-24 01:46:38 +00:00
|
|
|
#include "DebugEvent.h"
|
2009-06-25 23:51:09 +00:00
|
|
|
#include "ImageDebugInfoProvider.h"
|
2009-06-24 01:46:38 +00:00
|
|
|
#include "Thread.h"
|
|
|
|
|
|
|
|
|
2009-06-25 23:51:09 +00:00
|
|
|
class BreakpointManager;
|
2009-06-24 01:46:38 +00:00
|
|
|
class DebuggerInterface;
|
2009-06-25 23:51:09 +00:00
|
|
|
class StackFrame;
|
|
|
|
class Statement;
|
2009-06-24 01:46:38 +00:00
|
|
|
class Worker;
|
|
|
|
|
|
|
|
|
|
|
|
class ThreadHandler : public Referenceable,
|
2009-06-25 23:51:09 +00:00
|
|
|
public HashTableLink<ThreadHandler>, private ImageDebugInfoProvider,
|
|
|
|
private BreakpointClient {
|
2009-06-24 01:46:38 +00:00
|
|
|
public:
|
2009-07-22 19:20:06 +00:00
|
|
|
ThreadHandler(Thread* thread, Worker* worker,
|
2009-06-25 23:51:09 +00:00
|
|
|
DebuggerInterface* debuggerInterface,
|
|
|
|
BreakpointManager* breakpointManager);
|
2009-06-24 01:46:38 +00:00
|
|
|
~ThreadHandler();
|
|
|
|
|
|
|
|
void Init();
|
|
|
|
|
|
|
|
thread_id ThreadID() const { return fThread->ID(); }
|
|
|
|
Thread* GetThread() const { return fThread; }
|
|
|
|
|
2009-07-03 14:23:19 +00:00
|
|
|
status_t SetBreakpointAndRun(target_addr_t address);
|
|
|
|
// team lock held
|
|
|
|
|
2009-06-25 23:51:09 +00:00
|
|
|
// All Handle*() methods are invoked in team debugger thread,
|
|
|
|
// looper lock held.
|
2009-06-24 01:46:38 +00:00
|
|
|
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:
|
2009-06-25 23:51:09 +00:00
|
|
|
// ImageDebugInfoProvider
|
|
|
|
virtual status_t GetImageDebugInfo(Image* image,
|
|
|
|
ImageDebugInfo*& _info);
|
|
|
|
|
2009-06-24 01:46:38 +00:00
|
|
|
bool _HandleThreadStopped(CpuState* cpuState);
|
|
|
|
|
|
|
|
void _SetThreadState(uint32 state,
|
|
|
|
CpuState* cpuState);
|
|
|
|
|
2009-06-25 23:51:09 +00:00
|
|
|
Statement* _GetStatementAtInstructionPointer(
|
|
|
|
StackFrame* frame);
|
|
|
|
|
|
|
|
void _StepFallback();
|
|
|
|
bool _DoStepOver(CpuState* cpuState);
|
|
|
|
|
|
|
|
status_t _InstallTemporaryBreakpoint(
|
|
|
|
target_addr_t address);
|
|
|
|
void _UninstallTemporaryBreakpoint();
|
|
|
|
void _ClearContinuationState();
|
|
|
|
void _RunThread(target_addr_t instructionPointer);
|
|
|
|
void _SingleStepThread(
|
|
|
|
target_addr_t instructionPointer);
|
|
|
|
|
|
|
|
|
|
|
|
bool _HandleBreakpointHitStep(CpuState* cpuState);
|
|
|
|
bool _HandleSingleStepStep(CpuState* cpuState);
|
|
|
|
|
2009-06-24 01:46:38 +00:00
|
|
|
private:
|
|
|
|
Thread* fThread;
|
|
|
|
Worker* fWorker;
|
|
|
|
DebuggerInterface* fDebuggerInterface;
|
2009-06-25 23:51:09 +00:00
|
|
|
BreakpointManager* fBreakpointManager;
|
|
|
|
uint32 fStepMode;
|
|
|
|
Statement* fStepStatement;
|
|
|
|
target_addr_t fBreakpointAddress;
|
|
|
|
target_addr_t fPreviousInstructionPointer;
|
|
|
|
bool fSingleStepping;
|
2009-06-24 01:46:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
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
|