1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2013-2016, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef TEAM_DEBUGGER_H
7#define TEAM_DEBUGGER_H
8
9
10#include <debugger.h>
11#include <Looper.h>
12
13#include "Team.h"
14#include "TeamSettings.h"
15#include "ThreadHandler.h"
16#include "UserInterface.h"
17#include "util/Worker.h"
18
19
20class DebugEvent;
21class DebuggerInterface;
22class DebugReportGenerator;
23class FileManager;
24class ImageCreatedEvent;
25class ImageDebugInfoLoadingState;
26class ImageDeletedEvent;
27class PostSyscallEvent;
28class SettingsManager;
29class TeamDebugInfo;
30class TeamDeletedEvent;
31class TeamExecEvent;
32class TeamMemoryBlockManager;
33class Thread;
34class ThreadCreatedEvent;
35class ThreadDeletedEvent;
36class ThreadRenamedEvent;
37class ThreadPriorityChangedEvent;
38class WatchpointManager;
39
40
41class TeamDebugger : public BLooper, private UserInterfaceListener,
42	private JobListener, private Team::Listener {
43public:
44	class Listener;
45
46public:
47								TeamDebugger(Listener* listener,
48									UserInterface* userInterface,
49									SettingsManager* settingsManager);
50								~TeamDebugger();
51
52			status_t			Init(DebuggerInterface* interface,
53									thread_id threadID, int argc,
54									const char* const* argv,
55									bool stopInMain);
56
57			void				Activate();
58
59			team_id				TeamID() const	{ return fTeamID; }
60
61			bool				IsPostMortem() const { return fIsPostMortem; }
62
63			int					ArgumentCount() const
64									{ return fCommandLineArgc; }
65			const char**		Arguments() const
66									{ return fCommandLineArgv; }
67			SettingsManager*	GetSettingsManager() const
68									{ return fSettingsManager; }
69			UserInterface*		GetUserInterface() const
70									{ return fUserInterface; }
71
72	virtual	void				MessageReceived(BMessage* message);
73
74private:
75	// UserInterfaceListener
76	virtual	void				FunctionSourceCodeRequested(
77									FunctionInstance* function,
78									bool forceDisassembly = false);
79	virtual void				SourceEntryLocateRequested(
80									const char* sourcePath,
81									const char* locatedPath);
82	virtual void				SourceEntryInvalidateRequested(
83									LocatableFile* sourceFile);
84	virtual	void				ImageDebugInfoRequested(Image* image);
85	virtual	void				ValueNodeValueRequested(CpuState* cpuState,
86									ValueNodeContainer* container,
87									ValueNode* valueNode);
88	virtual	void				ValueNodeWriteRequested(ValueNode* node,
89									CpuState* state,
90									Value* newValue);
91	virtual	void				ThreadActionRequested(thread_id threadID,
92									uint32 action, target_addr_t address);
93
94	virtual	void				SetBreakpointRequested(target_addr_t address,
95									bool enabled, bool hidden = false);
96	virtual	void				SetBreakpointEnabledRequested(
97									UserBreakpoint* breakpoint,
98									bool enabled);
99	virtual	void				SetBreakpointConditionRequested(
100									UserBreakpoint* breakpoint,
101									const char* condition);
102	virtual	void				ClearBreakpointConditionRequested(
103									UserBreakpoint* breakpoint);
104	virtual	void				ClearBreakpointRequested(target_addr_t address);
105	virtual	void				ClearBreakpointRequested(
106									UserBreakpoint* breakpoint);
107
108	virtual	void				SetStopOnImageLoadRequested(bool enabled,
109									bool useImageNames);
110	virtual	void				AddStopImageNameRequested(
111									const char* name);
112	virtual	void				RemoveStopImageNameRequested(
113									const char* name);
114
115	virtual	void				SetDefaultSignalDispositionRequested(
116									int32 disposition);
117	virtual	void				SetCustomSignalDispositionRequested(
118									int32 signal, int32 disposition);
119	virtual	void				RemoveCustomSignalDispositionRequested(
120									int32 signal);
121
122	virtual	void				SetWatchpointRequested(target_addr_t address,
123									uint32 type, int32 length, bool enabled);
124	virtual	void				SetWatchpointEnabledRequested(
125									Watchpoint *watchpoint, bool enabled);
126	virtual	void				ClearWatchpointRequested(target_addr_t address);
127	virtual	void				ClearWatchpointRequested(
128									Watchpoint* breakpoint);
129
130	virtual void				InspectRequested(target_addr_t address,
131									TeamMemoryBlock::Listener* listener);
132	virtual	void				MemoryWriteRequested(target_addr_t address,
133									const void* data, target_size_t size);
134
135	virtual	void				ExpressionEvaluationRequested(
136									SourceLanguage* language,
137									ExpressionInfo* info,
138									StackFrame* frame = NULL,
139									::Thread* thread = NULL);
140
141	virtual void				DebugReportRequested(entry_ref* targetPath);
142
143	virtual	void				WriteCoreFileRequested(entry_ref* targetPath);
144
145	virtual	void				TeamRestartRequested();
146
147	virtual	bool				UserInterfaceQuitRequested(
148									QuitOption quitOption);
149
150	// JobListener
151	virtual	void				JobStarted(Job* job);
152	virtual	void				JobDone(Job* job);
153	virtual	void				JobWaitingForInput(Job* job);
154	virtual	void				JobFailed(Job* job);
155	virtual	void				JobAborted(Job* job);
156
157	// Team::Listener
158	virtual	void				ThreadStateChanged(
159									const ::Team::ThreadEvent& event);
160	virtual	void				ThreadCpuStateChanged(
161									const ::Team::ThreadEvent& event);
162	virtual	void				ThreadStackTraceChanged(
163									const ::Team::ThreadEvent& event);
164	virtual	void				ImageDebugInfoChanged(
165									const ::Team::ImageEvent& event);
166
167private:
168	struct ImageHandler;
169	struct ImageHandlerHashDefinition;
170	struct ImageInfoPendingThread;
171	struct ImageInfoPendingThreadHashDefinition;
172
173	typedef BOpenHashTable<ImageHandlerHashDefinition> ImageHandlerTable;
174	typedef BOpenHashTable<ImageInfoPendingThreadHashDefinition>
175		ImageInfoPendingThreadTable;
176
177private:
178	static	status_t			_DebugEventListenerEntry(void* data);
179			status_t			_DebugEventListener();
180
181			void				_HandleDebuggerMessage(DebugEvent* event);
182
183			bool				_HandleTeamDeleted(
184									TeamDeletedEvent* event);
185			bool				_HandleThreadCreated(
186									ThreadCreatedEvent* event);
187			bool				_HandleThreadRenamed(
188									ThreadRenamedEvent* event);
189			bool				_HandleThreadPriorityChanged(
190									ThreadPriorityChangedEvent* event);
191			bool				_HandleThreadDeleted(
192									ThreadDeletedEvent* event);
193			bool				_HandleImageCreated(
194									ImageCreatedEvent* event);
195			bool				_HandleImageDeleted(
196									ImageDeletedEvent* event);
197			bool				_HandlePostSyscall(
198									PostSyscallEvent* event);
199
200			void				_PrepareForTeamExec(TeamExecEvent* event);
201
202			void				_HandleImageDebugInfoChanged(image_id imageID);
203			void				_HandleImageFileChanged(image_id imageID);
204
205			void				_HandleSetUserBreakpoint(target_addr_t address,
206									bool enabled, bool hidden);
207			void				_HandleSetUserBreakpoint(
208									UserBreakpoint* breakpoint, bool enabled);
209			void				_HandleClearUserBreakpoint(
210									target_addr_t address);
211			void				_HandleClearUserBreakpoint(
212									UserBreakpoint* breakpoint);
213
214			void				_HandleSetWatchpoint(target_addr_t address,
215									uint32 type, int32 length, 	bool enabled);
216			void				_HandleSetWatchpoint(
217									Watchpoint* watchpoint, bool enabled);
218			void				_HandleClearWatchpoint(	target_addr_t address);
219			void				_HandleClearWatchpoint(Watchpoint* watchpoint);
220
221			void				_HandleInspectAddress(
222									target_addr_t address,
223									TeamMemoryBlock::Listener* listener);
224			void				_HandleWriteMemory(
225									target_addr_t address, void* data,
226									target_size_t size);
227
228			void				_HandleEvaluateExpression(
229									SourceLanguage* language,
230									ExpressionInfo* info,
231									StackFrame* frame,
232									::Thread* thread);
233
234			void				_HandleWriteCoreFile(const entry_ref& ref);
235
236			status_t			_HandleSetArguments(int argc,
237									const char* const* argv);
238
239			void				_HandleDebugInfoJobUserInput(
240									ImageDebugInfoLoadingState* state);
241
242			ThreadHandler*		_GetThreadHandler(thread_id threadID);
243
244			status_t			_AddImage(const ImageInfo& imageInfo,
245									Image** _image = NULL);
246
247			void				_LoadSettings();
248			void				_SaveSettings();
249
250			void				_NotifyUser(const char* title,
251									const char* text,...);
252
253			void				_ResetUserBackgroundStatusIfNeeded();
254									// updates user interface to
255									// ready/completed message
256									// for background work status
257
258private:
259			Listener*			fListener;
260			SettingsManager*	fSettingsManager;
261			::Team*				fTeam;
262			team_id				fTeamID;
263			bool				fIsPostMortem;
264			ThreadHandlerTable	fThreadHandlers;
265									// protected by the team lock
266			ImageHandlerTable*	fImageHandlers;
267			ImageInfoPendingThreadTable* fImageInfoPendingThreads;
268			DebuggerInterface*	fDebuggerInterface;
269			TeamDebugInfo*		fTeamDebugInfo;
270			FileManager*		fFileManager;
271			Worker*				fWorker;
272			BreakpointManager*	fBreakpointManager;
273			WatchpointManager*	fWatchpointManager;
274			TeamMemoryBlockManager*
275								fMemoryBlockManager;
276			DebugReportGenerator*
277								fReportGenerator;
278			thread_id			fDebugEventListener;
279			UserInterface*		fUserInterface;
280	volatile bool				fTerminating;
281			bool				fKillTeamOnQuit;
282			TeamSettings		fTeamSettings;
283			int					fCommandLineArgc;
284			const char**		fCommandLineArgv;
285			bool				fExecPending;
286};
287
288
289class TeamDebugger::Listener {
290public:
291	virtual						~Listener();
292
293	virtual void				TeamDebuggerStarted(TeamDebugger* debugger) = 0;
294	virtual	void				TeamDebuggerRestartRequested(
295									TeamDebugger* debugger) = 0;
296	virtual	void				TeamDebuggerQuit(TeamDebugger* debugger) = 0;
297};
298
299
300#endif	// TEAM_DEBUGGER_H
301