1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2014-2016, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef THREAD_HANDLER_H
7#define THREAD_HANDLER_H
8
9
10#include <Referenceable.h>
11#include <util/OpenHashTable.h>
12
13#include "Breakpoint.h"
14#include "ImageDebugInfoProvider.h"
15#include "model/Thread.h"
16
17
18class BreakpointHitEvent;
19class BreakpointManager;
20class DebugEvent;
21class DebuggerCallEvent;
22class DebuggerInterface;
23class ExceptionOccurredEvent;
24class ExpressionResult;
25class ImageDebugInfoJobListener;
26class JobListener;
27class SignalReceivedEvent;
28class SingleStepEvent;
29class StackFrame;
30class Statement;
31class ThreadDebuggedEvent;
32class WatchpointHitEvent;
33class Worker;
34
35
36class ThreadHandler : public BReferenceable, private ImageDebugInfoProvider,
37	private BreakpointClient {
38public:
39								ThreadHandler(::Thread* thread, Worker* worker,
40									DebuggerInterface* debuggerInterface,
41									JobListener* listener,
42									BreakpointManager* breakpointManager);
43								~ThreadHandler();
44
45			void				Init();
46
47			thread_id			ThreadID() const	{ return fThread->ID(); }
48			::Thread*			GetThread() const	{ return fThread; }
49
50			status_t			SetBreakpointAndRun(target_addr_t address);
51									// team lock held
52
53			// All Handle*() methods are invoked in team debugger thread,
54			// looper lock held.
55			bool				HandleThreadDebugged(
56									ThreadDebuggedEvent* event,
57									const BString& stoppedReason = BString());
58			bool				HandleDebuggerCall(
59									DebuggerCallEvent* event);
60			bool				HandleBreakpointHit(
61									BreakpointHitEvent* event);
62			bool				HandleWatchpointHit(
63									WatchpointHitEvent* event);
64			bool				HandleSingleStep(
65									SingleStepEvent* event);
66			bool				HandleExceptionOccurred(
67									ExceptionOccurredEvent* event);
68			bool				HandleSignalReceived(
69									SignalReceivedEvent* event);
70
71			void				HandleThreadAction(uint32 action,
72									target_addr_t address);
73
74			void				HandleThreadStateChanged();
75			void				HandleCpuStateChanged();
76			void				HandleStackTraceChanged();
77
78private:
79			friend class ExpressionEvaluationListener;
80
81private:
82	// ImageDebugInfoProvider
83	virtual	status_t			GetImageDebugInfo(Image* image,
84									ImageDebugInfo*& _info);
85
86			bool				_HandleThreadStopped(CpuState* cpuState,
87									uint32 stoppedReason,
88									const BString& stoppedReasonInfo
89										= BString());
90
91			bool				_HandleSetAddress(CpuState* cpuState,
92									target_addr_t address);
93
94			void				_SetThreadState(uint32 state,
95									CpuState* cpuState, uint32 stoppedReason,
96									const BString& stoppedReasonInfo);
97
98			Statement*			_GetStatementAtInstructionPointer(
99									StackFrame* frame);
100
101			void				_StepFallback();
102			bool				_DoStepOver(CpuState* cpuState);
103
104			status_t			_InstallTemporaryBreakpoint(
105									target_addr_t address);
106			void				_UninstallTemporaryBreakpoint();
107			void				_ClearContinuationState();
108			void				_RunThread(target_addr_t instructionPointer);
109			void				_SingleStepThread(
110									target_addr_t instructionPointer);
111
112			bool				_HandleBreakpointConditionIfNeeded(
113									CpuState* cpuState);
114			void				_HandleBreakpointConditionEvaluated(
115									ExpressionResult* value);
116			bool				_CheckStopCondition();
117
118			bool				_HandleBreakpointHitStep(CpuState* cpuState);
119			bool				_HandleSingleStepStep(CpuState* cpuState);
120
121			bool				_HasExitedFrame(target_addr_t framePointer)
122									const;
123
124private:
125			::Thread*			fThread;
126			Worker*				fWorker;
127			DebuggerInterface*	fDebuggerInterface;
128			JobListener*		fJobListener;
129			BreakpointManager*	fBreakpointManager;
130			uint32				fStepMode;
131			Statement*			fStepStatement;
132			target_addr_t		fBreakpointAddress;
133			target_addr_t		fSteppedOverFunctionAddress;
134			target_addr_t		fPreviousInstructionPointer;
135			target_addr_t		fPreviousFrameAddress;
136			bool				fSingleStepping;
137			sem_id				fConditionWaitSem;
138			ExpressionResult*	fConditionResult;
139
140public:
141			ThreadHandler*		fNext;
142};
143
144
145struct ThreadHandlerHashDefinition {
146	typedef thread_id		KeyType;
147	typedef	ThreadHandler	ValueType;
148
149	size_t HashKey(thread_id key) const
150	{
151		return (size_t)key;
152	}
153
154	size_t Hash(const ThreadHandler* value) const
155	{
156		return HashKey(value->ThreadID());
157	}
158
159	bool Compare(thread_id key, ThreadHandler* value) const
160	{
161		return value->ThreadID() == key;
162	}
163
164	ThreadHandler*& GetLink(ThreadHandler* value) const
165	{
166		return value->fNext;
167	}
168};
169
170typedef BOpenHashTable<ThreadHandlerHashDefinition> ThreadHandlerTable;
171
172
173#endif	// THREAD_HANDLER_H
174