xref: /haiku/headers/private/debugger/controllers/TeamDebugger.h (revision 05fc1277c47440dc36134816d70e5723c99cfcd2)
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 
20 class DebugEvent;
21 class DebuggerInterface;
22 class DebugReportGenerator;
23 class FileManager;
24 class ImageCreatedEvent;
25 class ImageDebugInfoLoadingState;
26 class ImageDeletedEvent;
27 class PostSyscallEvent;
28 class SettingsManager;
29 class TeamDebugInfo;
30 class TeamDeletedEvent;
31 class TeamExecEvent;
32 class TeamMemoryBlockManager;
33 class Thread;
34 class ThreadCreatedEvent;
35 class ThreadDeletedEvent;
36 class ThreadRenamedEvent;
37 class ThreadPriorityChangedEvent;
38 class WatchpointManager;
39 
40 
41 class TeamDebugger : public BLooper, private UserInterfaceListener,
42 	private JobListener, private Team::Listener {
43 public:
44 	class Listener;
45 
46 public:
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 
TeamID()59 			team_id				TeamID() const	{ return fTeamID; }
60 
IsPostMortem()61 			bool				IsPostMortem() const { return fIsPostMortem; }
62 
ArgumentCount()63 			int					ArgumentCount() const
64 									{ return fCommandLineArgc; }
Arguments()65 			const char**		Arguments() const
66 									{ return fCommandLineArgv; }
GetSettingsManager()67 			SettingsManager*	GetSettingsManager() const
68 									{ return fSettingsManager; }
GetUserInterface()69 			UserInterface*		GetUserInterface() const
70 									{ return fUserInterface; }
71 
72 	virtual	void				MessageReceived(BMessage* message);
73 
74 private:
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 
167 private:
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 
177 private:
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 
258 private:
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 
289 class TeamDebugger::Listener {
290 public:
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